Dire hai a che fare con qualche altro delimitatore, come ad esempio una scheda \t
, invece di un ritorno a capo \n
.
Un approccio più generale ai delimitatori è l'uso di getc()
, che acquisisce un carattere alla volta.
Si noti che getc()
restituisce un int
, in modo che possiamo verificare l'uguaglianza con EOF
.
secondo luogo, definiamo un array line[BUFFER_MAX_LENGTH]
di tipo char
, al fine di memorizzare fino a BUFFER_MAX_LENGTH-1
caratteri sullo stack (dobbiamo salvare quella dell'ultimo carattere di un personaggio \0
terminatore).
L'utilizzo di un array evita la necessità di utilizzare malloc
e free
per creare un puntatore di caratteri della lunghezza corretta nell'heap.
#define BUFFER_MAX_LENGTH 1024
int main(int argc, char* argv[])
{
FILE *file = NULL;
char line[BUFFER_MAX_LENGTH];
int tempChar;
unsigned int tempCharIdx = 0U;
if (argc == 2)
file = fopen(argv[1], "r");
else {
fprintf(stderr, "error: wrong number of arguments\n"
"usage: %s textfile\n", argv[0]);
return EXIT_FAILURE;
}
if (!file) {
fprintf(stderr, "error: could not open textfile: %s\n", argv[1]);
return EXIT_FAILURE;
}
/* get a character from the file pointer */
while(tempChar = fgetc(file))
{
/* avoid buffer overflow error */
if (tempCharIdx == BUFFER_MAX_LENGTH) {
fprintf(stderr, "error: line is too long. increase BUFFER_MAX_LENGTH.\n");
return EXIT_FAILURE;
}
/* test character value */
if (tempChar == EOF) {
line[tempCharIdx] = '\0';
fprintf(stdout, "%s\n", line);
break;
}
else if (tempChar == '\n') {
line[tempCharIdx] = '\0';
tempCharIdx = 0U;
fprintf(stdout, "%s\n", line);
continue;
}
else
line[tempCharIdx++] = (char)tempChar;
}
return EXIT_SUCCESS;
}
Se è necessario utilizzare un char *
, allora è ancora possibile utilizzare questo codice, ma si strdup()
la matrice line[]
, una volta che è riempito con il valore di una riga di input. È necessario free
questa stringa duplicato una volta che hai fatto con esso, o avrai una perdita di memoria:
#define BUFFER_MAX_LENGTH 1024
int main(int argc, char* argv[])
{
FILE *file = NULL;
char line[BUFFER_MAX_LENGTH];
int tempChar;
unsigned int tempCharIdx = 0U;
char *dynamicLine = NULL;
if (argc == 2)
file = fopen(argv[1], "r");
else {
fprintf(stderr, "error: wrong number of arguments\n"
"usage: %s textfile\n", argv[0]);
return EXIT_FAILURE;
}
if (!file) {
fprintf(stderr, "error: could not open textfile: %s\n", argv[1]);
return EXIT_FAILURE;
}
while(tempChar = fgetc(file))
{
/* avoid buffer overflow error */
if (tempCharIdx == BUFFER_MAX_LENGTH) {
fprintf(stderr, "error: line is too long. increase BUFFER_MAX_LENGTH.\n");
return EXIT_FAILURE;
}
/* test character value */
if (tempChar == EOF) {
line[tempCharIdx] = '\0';
dynamicLine = strdup(line);
fprintf(stdout, "%s\n", dynamicLine);
free(dynamicLine);
dynamicLine = NULL;
break;
}
else if (tempChar == '\n') {
line[tempCharIdx] = '\0';
tempCharIdx = 0U;
dynamicLine = strdup(line);
fprintf(stdout, "%s\n", dynamicLine);
free(dynamicLine);
dynamicLine = NULL;
continue;
}
else
line[tempCharIdx++] = (char)tempChar;
}
return EXIT_SUCCESS;
}
Questo codice non deve anche compilare. 'sscanf (riga, nomefile,"% s ");' dovrebbe essere 'sscanf (riga, file,"% s ");' – Mawg
Si noti che ['while (! feof (file))' è sempre sbagliato] (http : //stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong). –
Possibile duplicato di [C leggere file riga per riga] (https://stackoverflow.com/questions/3501338/c-read-file-line-by-line) –