PDA

Visualizza la versione completa : [C] Passaggio da file a matrice


principino 47
23-02-2011, 14:33
salve a tutti :)
sono nuovo del forum, quindi chiedo perdono per errori/incomprensioni...
ho un problema con un programmino in c..

dovrei salvare carattere per carattere (spazi inclusi) il contenuto di un file in un vettore matrice...
ogni riga del file inizia e finisce con '|'..

ho scritto questo codice:

fp = fopen("forzaN.txt","r");
if(fp == NULL) {
printf("ATTENZIONE: il file non puo essere aperto per la lettura\n");
return 1;
}

else{
while (c != EOF){
do{
c = fgetc (fp);
if (c != '|' || c != '\n'){
schema[riga][colonna] = c;
riga++;
}
} while (c != '\n');
colonna++;
}
}

nel momento in cui "avvio" il programma su cygwin mi compare il messaggio:
"segmentatio fault (core dumped)" :cry:

qualcuno mi sa aiutare??
grazie

_Alfabetagamma_
23-02-2011, 16:52
In teoria l'errore potrebbe essere dovuto dal fatto che con il tuo codice tu possa invadere aree di memoria a te non destinate. Infatti in schema[colonna][riga] incrementi continuamente riga colonna, ma se superassi le dimensioni dell'array di array? Poi se ogni riga inizia e termina con '|' perchè all'interno dici if(c!='\n') ?? Secondo problema se EOF funziona come feof(puntatore a file) devi prima prendere un carattere e poi controllare se il file è finito. cioè così:




c=fgetc(fp)

while(!feof(fp))
{
.......

c=fgetc(fp);
}

Ad occhio non vedo altri possibili problemi :)

principino 47
23-02-2011, 21:04
Originariamente inviato da _Alfabetagamma_
In teoria l'errore potrebbe essere dovuto dal fatto che con il tuo codice tu possa invadere aree di memoria a te non destinate. Infatti in schema[colonna][riga] incrementi continuamente riga colonna, ma se superassi le dimensioni dell'array di array? Poi se ogni riga inizia e termina con '|' perchè all'interno dici if(c!='\n') ?? Secondo problema se EOF funziona come feof(puntatore a file) devi prima prendere un carattere e poi controllare se il file è finito. cioè così:




c=fgetc(fp)

while(!feof(fp))
{
.......

c=fgetc(fp);
}

Ad occhio non vedo altri possibili problemi :)

ok grazie..
Lo avevo già fatto in questo modo, nel programma limito comunque i due valori, ma in questo modo continua a darmi l'errore...
non so se possa essere qualche bug del compilatore, perchè con la vecchia versione andava alla perfezione...

_Alfabetagamma_
23-02-2011, 23:17
Magari c'è un errore nel resto del codice, qui mi sembra tutto a posto :)

principino 47
24-02-2011, 00:47
Originariamente inviato da _Alfabetagamma_
Magari c'è un errore nel resto del codice, qui mi sembra tutto a posto :)

lo ho riscritto come mi hai consigliato, almeno credo, ma mi compare ancora l'errore "segmentation fault"...
se però compilo singole righe lette va tutto liscio...ma non riesco a trovare l'errore...

fp = fopen("forzaN.txt","r");
if(fp == NULL) {
printf("ATTENZIONE: il file non puo essere aperto per la lettura\n");
return 0;
}

while (!feof(fp)|| c!='_'){
c=fgetc(fp);
while (c!='\n'){

c = fgetc(fp);
if ( c!='|' && c!='_'){
printf("%c",c);
schema [riga][colonna] = c;
colonna++;
ncolonne++;
}
}
/*printf("\n"); */
colonna=0;
riga++;
}

Laikius91
24-02-2011, 09:40
Originariamente inviato da principino 47
lo ho riscritto come mi hai consigliato, almeno credo, ma mi compare ancora l'errore "segmentation fault"...
se però compilo singole righe lette va tutto liscio...ma non riesco a trovare l'errore...

fp = fopen("forzaN.txt","r");
if(fp == NULL) {
printf("ATTENZIONE: il file non puo essere aperto per la lettura\n");
return 0;
}

while (!feof(fp)|| c!='_'){
c=fgetc(fp);
while (c!='\n'){

c = fgetc(fp);
if ( c!='|' && c!='_'){
printf("%c",c);
schema [riga][colonna] = c;
colonna++;
ncolonne++;
}
}
/*printf("\n"); */
colonna=0;
riga++;
}


A che punto dell'esecuzione ti va in segmentation fault?

principino 47
24-02-2011, 10:45
Originariamente inviato da Laikius91
A che punto dell'esecuzione ti va in segmentation fault?

quando compilo la parte di codice che ho scritto sopra...
ovviamente sopra dichiaro le variabili e l'indispensabile per il programma...
ho modiicato alcune righe, ma l'esito è sempre lo stesso, comunque nella matrice i dati sono salvati correttamente...

Laikius91
25-02-2011, 11:23
Originariamente inviato da principino 47
quando compilo la parte di codice che ho scritto sopra...
ovviamente sopra dichiaro le variabili e l'indispensabile per il programma...
ho modiicato alcune righe, ma l'esito è sempre lo stesso, comunque nella matrice i dati sono salvati correttamente...


Bè distinguiamo tra compilazione ed esecuzione: quando compili crei l'eseguibile, che per l'appunto vai ad eseguire e a quel punto avviene l'errore di segmentation...
Quello che ti chiedevo è: quando fai partire il programma va subito in segmentation fault? Non esegue neanche un ciclo di lettura?

Da quello che ho letto, la feof() funziona in maniera autonoma, non occorre che sia già avvenuta la lettura di parte del file, quindi la dicitura:



while (!feof(fp))
{
/* lettura dal file */
}


è corretta...

Sinceramente ho difficoltà a capire le condizioni che imposti nei vari while, mi sembrano parecchio confusionarie... In ogni caso, quando leggi da file e hai dei delimitatori fisici (ossia caratteri speciali, come nel tuo caso '|'), conviene utilizzare dei cicli do..while, ad esempio:



while (!feof(fp))
{
fgetc (fp); /* leggi il primo '|' */
do
{
c = fgetc (fp); /* leggi i caratteri compresi tra i due '|' */
if (c != '|')
{
schema [riga][colonna] = c;
colonna++;
}
}
while (c != '|');

fgetc (fp); /* leggi il carattere '\n' */
riga++;
}


Chiaramente, come era stato evidenziato prima, in questo ciclo non vi è nessun controllo sulle dimensioni e questo può essere un grave errore: occorre SEMPRE controllare di non oltrepassare le dimensioni fisiche di array o matrici! Quindi dovresti implementare anche questo controllo, ad esempio passando alla funzione che si fa carico della lettura anche la dimensione di righe e colonne della matrice e controllando ad ogni ciclo e sottociclo di non aver oltrepassato tali dimensioni!

principino 47
25-02-2011, 14:02
Chiaramente, come era stato evidenziato prima, in questo ciclo non vi è nessun controllo sulle dimensioni e questo può essere un grave errore: occorre SEMPRE controllare di non oltrepassare le dimensioni fisiche di array o matrici! Quindi dovresti implementare anche questo controllo, ad esempio passando alla funzione che si fa carico della lettura anche la dimensione di righe e colonne della matrice e controllando ad ogni ciclo e sottociclo di non aver oltrepassato tali dimensioni! [/QUOTE]

effettivamente ora sembra funzionare...grazie
per il controllo ho aggiunto le condizioni necessarie al while...

Laikius91
25-02-2011, 15:23
Originariamente inviato da principino 47
Chiaramente, come era stato evidenziato prima, in questo ciclo non vi è nessun controllo sulle dimensioni e questo può essere un grave errore: occorre SEMPRE controllare di non oltrepassare le dimensioni fisiche di array o matrici! Quindi dovresti implementare anche questo controllo, ad esempio passando alla funzione che si fa carico della lettura anche la dimensione di righe e colonne della matrice e controllando ad ogni ciclo e sottociclo di non aver oltrepassato tali dimensioni!

effettivamente ora sembra funzionare...grazie
per il controllo ho aggiunto le condizioni necessarie al while...

Probabilmente l'errore di segmentation sorgeva nel primo controllo eseguito dal ciclo che avevi scritto, quando andava ad effettura un controllo sulla variabile c che ancora non era stata inizializzata!
Hai risolto utilizzando il ciclo che ti ho postato io quindi?
Lieto di averti aiutato! :)

Loading