Reputation: 427
I am a little bit desperate as I wasted my last 4 hours looking for a solution for a simple/stupid thing. I have a project in school in which I must read integers from a text file and then calculate the maximum of them. The thing is that these numbers are not necessarily separated by spaces, but also tabs ( \t ) or newlines (\n). I use the fscanf function to read my integers, but the problem is that after the last number I have a space in my file, so it reads 2 times the last number(I do not know why). Normally one would say "Just delete that space", but my teacher is going to test the program in several manners, and he warned us that the program must be robust (we have to be able to manage the spaces, \t, \n so we can read correctly the numbers, so this is why he left on purpose a space after the last number). Here is my code with the sample text:
FILE* file = NULL;
int *t = NULL, *new_size = NULL;
int temp, count;
file = fopen(argv[1],"r");
do
{
fscanf(file,"%d",&temp);
count++;
new_size = (int*) realloc (t, count * sizeof(int));
if (new_size != NULL)
{
t = new_size;
t[count-1] = temp;
}
else
{
free(t);
puts("Erreur d\'allocation memoire!\n");
exit(1);
}
} while(!feof(file));
fclose(file);
printf ("Numbers read\n:");
for(i = 0; i < count; i++)
{
printf ("%d ", t[i]);
}
And my argument is a file named data.txt which contains: 3 1 7 0 4 9 6 150 and a \n at the end. So basically, my program reads the first 8 integers, and after that, since it is not EndOfFile, it still reads the last one (150) again. So my output is :
Numbers read:
3 1 7 0 4 9 6 150 150
Could anyone tell me what I should do in order to make my program more robust? I need to manage the same type os error if there is a space at the end, or even a tab (\t
).
Any help would be appreciated!
Upvotes: 3
Views: 546
Reputation: 21966
If the numbers are separated by a space, then you can read a space with fscanf and then an integer.To make the program robust, always see if fscanf fails.If it fails then stop reading integers, else continue.
bool good=true;
while(good)
{
char separator;
if(fscanf(file,"%c",&separator)==1)
{
if(separator!=' ' && separator!='\t' && separator!='\n')
{
fprintf(stderr,"Illegal character found in file");
// You can choose if break the loop setting good to false, or
// if to continue, this depends on your assignment
}
if(fscanf(file,"%d",&temp)==1)
{
< Push temp to your list/array >
}
else
{
good=false;
}
}
else
{
good=false;
}
}
Upvotes: 0
Reputation: 121971
Use the result of fscanf()
, which returns the number of assignments made, as the terminating condition of the loop. After the loop check that EOF was reached and the loop did not terminate due to some other failure.
Upvotes: 2
Reputation: 183878
Check the return value of fscanf
if (fscanf(file,"%d",&temp) != 1) break;
and break out of the loop if it doesn't find a number anymore. fscanf
returns the number of successful conversions, and that should be used for error checking and handling.
Upvotes: 2