PDA

View Full Version : [C] Problema nell'apertura di un file


gscaparrotti
19-12-2013, 16:12
Ciao a tutti, ho scritto un semplice programma che, preso in ingresso un file di testo, ne restituisce un altro in cui alcune lettere sono scambiate.
I nomi del file di input e di quello di output sono immessi da tastiera, e il problema sta nel fatto che, mentre il file di ingresso viene aperto correttamente, quello in uscita restituisce sempre un errore. la cosa strana è che, se al posto di far inserire all'utente il nome del file lo specifico manualmente come argomento della funzione fopen, tutto funziona correttamente.

Grazie in anticipo a chi mi aiuterà!

#include <stdio.h>
#include <stdlib.h>

int main() {
FILE *input;
FILE *output;
char nome_input[20];
char nome_output[20];
unsigned char stringa[2];
unsigned char inverti1, inverti2, inverti3, inverti4;
unsigned char carattere;
printf("GESTIONE DI FILE DI TESTO");
printf("\n\nInserire il nome del file di origine: ");
gets(nome_input);
printf("\nInserire il nome del file di destinazione: ");
gets(nome_output);
printf("\nInserire i due caratteri da invertire: ");
scanf("%s", stringa);
inverti1=stringa[0];
inverti2=stringa[1];
inverti3=inverti1-32;
inverti4=inverti2-32;
if((input=fopen(nome_input, "r"))==NULL)
printf("\n\nErrore nell\'apertura del file di origine\n");
if((output=fopen(nome_output, "w"))==NULL)
printf("\n\nErrore nell\'apertura del file di destinazione\n");
while(!feof(input)) {
carattere=getc(input);
if(carattere==inverti1)
putc(inverti2, output);
else if(carattere==inverti2)
putc(inverti1, output);
else if(carattere==inverti3)
putc(inverti4, output);
else if(carattere==inverti4)
putc(inverti3, output);
else
putc(carattere, output);
}
printf("\nFatto!\n\n");
fclose(input);
fclose(output);
system("pause");
return 0;
}

GByTe87
19-12-2013, 16:27
Errore nel senso che fopen restituisce NULL e quindi tutto muore li?

Hint: fopen in caso di errore imposta la variabile errno in modo che contenga dati relativi all'errore, oltre a restituire NULL. Qua (http://www.beej.us/guide/bgnet/output/html/multipage/perrorman.html) trovi un esempio. :)

gscaparrotti
20-12-2013, 08:23
Ho provato a usare perror e mi dice Invalid Argument, ma non capisco perchè succede solo con uno dei due file...

Oceans11
20-12-2013, 09:01
qual'è l'input che dai al programma?

ps: ti consiglio vivamente di non usare la gets(), visto che non ha nessun controllo sulla lunghezza della stringa.

gscaparrotti
20-12-2013, 09:11
scrivo rispettivamente testo.txt e output.txt

clockover
20-12-2013, 10:12
Con quale dei file ti da errore? quello di input o quello di output?
Come usi perror?

gscaparrotti
20-12-2013, 10:40
mi da errore con il file di output.

ho scritto così:

if((output=fopen(nome_output, "w"))==NULL) {
perror("\nErrore nell\'apertura del file di destinazione");
}

clockover
20-12-2013, 11:09
E' un po che non programmo in C comunque fai una prova, magari con un altro file

Fai una cosa del tipo

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

#define BSIZE 10

int main(int argn, char ** argv){
char buffer[BSIZE];
printf("Filename: ");
fgets(buffer, BSIZE, stdin);
FILE * fl = fopen(buffer, "r");
if(fl == NULL){
char * err = strerror(errno);
printf("Errore apertura file %s : %s\n", buffer, err);
exit(1);
}
return 0;
}

Fai una prova con questo e dopo fai una prova cambiando da "r" a "w" e riporta gli errori.

clockover
20-12-2013, 11:22
Ehmm una cosa ho dimenticato. Tutto questo tempo lontano dal C me lo ha fatto passare di mente.
Io ho usato fgets, che è molto più sicuro di gets (che tra l'altro è stato anche deprecato).
fgets però, al contrario di gets, non sostituisce il newline ( \n ) con il null byte ( \0 ). Per ovviare al problema puoi inserire questa linea subito dopo la richiesta di input

buffer[strlen(buffer) - 1] = '\0';

Ciao

gscaparrotti
20-12-2013, 11:24
e se usassi scanf con %s come argomento?

clockover
20-12-2013, 11:29
e se usassi scanf con %s come argomento?

Per te ora il problema non è usare scanf o fgets o gets, il problema è capire perchè l'apertura del file fallisce. Hai provato il mio codice con l'aggiunta? Funziona? ;)

gscaparrotti
20-12-2013, 11:36
sì, funziona, però copiando il codice per l'inserimento del nome del file nel mio programma continua a darmi invalid argument...

clockover
20-12-2013, 11:37
sì, funziona, però copiando il codice per l'inserimento del nome del file nel mio programma continua a darmi invalid argument...

Mostraci ora il tuo codice modificato

gscaparrotti
20-12-2013, 11:40
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BSIZE 20

int main() {
FILE *input;
FILE *output;
char nome_input[BSIZE];
char buffer[BSIZE];
unsigned char stringa[2];
unsigned char inverti1, inverti2, inverti3, inverti4;
unsigned char carattere;
printf("GESTIONE DI FILE DI TESTO");
printf("\n\nInserire il nome del file di origine: ");
fgets(nome_input, BSIZE, stdin);
nome_input[strlen(nome_input) - 1] = '\0';
printf("\nInserire il nome del file di destinazione: ");
fgets(buffer, BSIZE, stdin);
buffer[strlen(buffer) - 1] = '\0';
printf("\nInserire i due caratteri da invertire: ");
scanf("%s", stringa);
inverti1=stringa[0];
inverti2=stringa[1];
inverti3=inverti1-32;
inverti4=inverti2-32;
if((input=fopen(nome_input, "r"))==NULL) {
perror("\nErrore nell\'apertura del file di origine");
}
if((output=fopen(buffer, "w"))==NULL) {
perror("\nErrore nell\'apertura del file di destinazione");
}
while(!feof(input)) {
carattere=getc(input);
if(carattere==inverti1)
putc(inverti2, output);
else if(carattere==inverti2)
putc(inverti1, output);
else if(carattere==inverti3)
putc(inverti4, output);
else if(carattere==inverti4)
putc(inverti3, output);
else
putc(carattere, output);
}
printf("\nFatto!\n\n");
fclose(input);
fclose(output);
system("pause");
return 0;
}

gscaparrotti
20-12-2013, 11:48
ehm... non so usare un debugger... :ops:

clockover
20-12-2013, 11:53
Prova così
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#define BSIZE 20

int main() {
FILE *input;
FILE *output;
char nome_input[BSIZE];
char buffer[BSIZE];
unsigned char stringa[2];
unsigned char inverti1, inverti2, inverti3, inverti4;
unsigned char carattere;
printf("GESTIONE DI FILE DI TESTO");

printf("\n\nInserire il nome del file di origine: ");
fgets(nome_input, BSIZE, stdin);
nome_input[strlen(nome_input) - 1] = '\0';

printf("\nInserire il nome del file di destinazione: ");
fgets(buffer, BSIZE, stdin);
buffer[strlen(buffer) - 1] = '\0';

printf("\nInserire i due caratteri da invertire: ");
scanf("%s", stringa);
inverti1=stringa[0];
inverti2=stringa[1];
inverti3=inverti1-32;
inverti4=inverti2-32;
if((input=fopen(nome_input, "r"))==NULL) {
// perror("\nErrore nell\'apertura del file di origine");
printf("Errore apertura %s: %s\n", nome_input, strerror(errno));
exit(1);
}
if((output=fopen(buffer, "w"))==NULL) {
// perror("\nErrore nell\'apertura del file di destinazione");
printf("Errore apertura %s: %s\n", buffer, strerror(errno));
exit(2);
}
while(!feof(input)) {
carattere=getc(input);
if(carattere==inverti1)
putc(inverti2, output);
else if(carattere==inverti2)
putc(inverti1, output);
else if(carattere==inverti3)
putc(inverti4, output);
else if(carattere==inverti4)
putc(inverti3, output);
else
putc(carattere, output);
}
printf("\nFatto!\n\n");
fclose(input);
fclose(output);
system("pause");
return 0;
}

bancodeipugni
20-12-2013, 14:19
provato a usare fdopen invece di fopen

e provato ad aprire in "w+" o "r+" ??

altra cosa: il nome del file da aprire/aggiornare lo dai relativo o assoluto (cioè che parte dalla radice dell'unità) ?

vbextreme
24-12-2013, 06:27
il problema non risiede nel codice,a parte quell'orrendo system.
La prima cosa da fare è disinstallare quella ciofeca di dev-c++ e installare un ide piu serio.
Sicuramente usi un windows superiore al xp e quindi se non hai i diritti non puoi scrivere i file dove ti pare e piace ma solo dove hai i diritti.
Prova quindi a scrivere come output il percorso completo di una cartella di cui hai i diritti.