trouble reading from file

B

bas

hey,

I am having a lot of trouble trying to get this program to work
properly. It is supposed to read integers from a file and place them
into the categories for inventory. The problem seems to be that the
program will only read the first line of integers from the file, and
just print them into all the categories. Any help or suggestions
woulud be great, I swear i probably tried everything

#include <stdio.h>

int main(void)
{

int PartNo[5];
float Price[5];
int QOH[5];
int ReorderPt[5];
int MinOrder[5];
int x[4];
int i;
int y;
FILE *Fp1;

Fp1 = fopen("data.txt", "r");
if ( Fp1 == NULL )
{
perror ( NULL );
}

for(y=0;y<5;y++)
{
for(i=0;i<4;i++)
fscanf(Fp1,"%d",&x);
PartNo[y] = ((x[0]*1000)+(x[1]*100)+(x[2]*10)+x[3]);
}

for(y=0;y<5;y++)
{
for(i=0;i<4;i++)
fscanf(Fp1, "%f", &x);
Price[y] = ((x[0]*1000)+(x[1]*100)+(x[2]*10)+x[3])/100;
}

for(y=0;y<5;y++)
{
for(i=0;i<4;i++)
fscanf(Fp1, "%d", &x);
QOH[y] = ((x[0]*1000)+(x[1]*100)+(x[2]*10)+x[3]);
}

for(y=0;y<5;y++)
{
for(i=0;i<4;i++)
fscanf(Fp1, "%f", &x);
ReorderPt[y] = ((x[0]*1000)+(x[1]*100)+(x[2]*10)+x[3]);
}

for(y=0;y<5;y++)
{
for(i=0;i<4;i++)
fscanf(Fp1, "%f", &x);
MinOrder[y] = ((x[0]*1000)+(x[1]*100)+(x[2]*10)+x[3]);
}

for(y=0;y<5;y++)
{
if(QOH[y]<ReorderPt[y])
QOH[y] = QOH[y]+MinOrder[y];
}

printf("\n\b |-----------------------------------------------------------|");
printf("\n\b |Part Number --- Price --- Quantity on Hand --- Reorder
Point --- Minimum Order |");
printf("\n\b |-----------------------------------------------------------|");
printf("\n | %4d --- %2.2f --- %2d --- %2d |", PartNo[0], Price[0],
QOH[0], ReorderPt[0], MinOrder[0]);
printf("\n | %4d --- %2.2f --- %2d --- %2d |", PartNo[1], Price[1],
QOH[1], ReorderPt[1], MinOrder[1]);
printf("\n | %4d --- %2.2f --- %2d --- %2d |", PartNo[2], Price[2],
QOH[2], ReorderPt[2], MinOrder[2]);
printf("\n | %4d --- %2.2f --- %2d --- %2d |", PartNo[3], Price[3],
QOH[3], ReorderPt[3], MinOrder[3]);
printf("\n | %4d --- %2.2f --- %2d --- %2d |", PartNo[4], Price[4],
QOH[4], ReorderPt[4], MinOrder[4]);
printf("\n\b |-----------------------------------------------------------|");

return 0;
}
 
R

Régis Troadec

bas said:
hey,
Hi,


I am having a lot of trouble trying to get this program to work
properly. It is supposed to read integers from a file and place them
into the categories for inventory. The problem seems to be that the
program will only read the first line of integers from the file, and
just print them into all the categories. Any help or suggestions
woulud be great, I swear i probably tried everything

#include <stdio.h>

int main(void)
{

int PartNo[5];
float Price[5];
int QOH[5];
int ReorderPt[5];
int MinOrder[5];
int x[4];
int i;
int y;
FILE *Fp1;

Fp1 = fopen("data.txt", "r");
if ( Fp1 == NULL )
{
perror ( NULL );
}

Be careful, perror() lets you to continue the program. fscanf might fail if
Fp1 is NULL.

[snipped]
for(y=0;y<5;y++)
{
for(i=0;i<4;i++)
fscanf(Fp1, "%f", &x);


Be careful, the format specifier %f (float) is different from the type of an
x (integer). It produces an undefined behavior.
Price[y] = ((x[0]*1000)+(x[1]*100)+(x[2]*10)+x[3])/100;

Price elements are floats, and it's a division between integers.

Price[y] = (float)((x[0]*1000)+(x[1]*100)+(x[2]*10)+x[3])/100.0;


[snipped]

Why not :

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

int main(void)
{
int i, y, x[4];
int PartNo[5], QOH[5], ReorderPt[5], MinOrder[5];
float Price[5];

FILE *Fp1;

Fp1 = fopen("data.txt", "r");

if (Fp1==NULL)
{
perror()
exit(EXIT_FAILURE);
}

do
{
/* Get a line with 4 integers */
fscanf(Fp1,"%d%d%d%d",&x[0],&x[1],&x[2],&x[3]);
for(y=0; y<5; y++)
{
PartNo[y] = ((x[0]*1000)+(x[1]*100)+(x[2]*10)+x[3]);
/* Price elements are floats*/
Price[y] = (float)((x[0]*1000)+(x[1]*100)+(x[2]*10)+x[3])/100.0;
QOH[y] = ((x[0]*1000)+(x[1]*100)+(x[2]*10)+x[3]);
ReorderPt[y] = ((x[0]*1000)+(x[1]*100)+(x[2]*10)+x[3]);
MinOrder[y] = ((x[0]*1000)+(x[1]*100)+(x[2]*10)+x[3]);

if(QOH[y]<ReorderPt[y])
{
QOH[y] = QOH[y]+MinOrder[y];
}
}

/* Print the different values*/

} while(!feof(Fp1) && !ferror(Fp1));

fclose(Fp1);
return EXIT_SUCCESS;
}

Regis
 
C

Chris Torek

while(!feof(Fp1) ...

This is virtually *guaranteed* to be wrong (about a 99.997% chance
in my experience, and the remaining .003% are just redundant :) ).
Now, let us find out whether it is:
do {
/* Get a line with 4 integers */
fscanf(Fp1,"%d%d%d%d",&x[0],&x[1],&x[2],&x[3]);

[snippage of code that uses the values in x[]]
} while(!feof(Fp1) && !ferror(Fp1));

The comment, "a line with 4 integers", suggests that the input
stream that Fp1 will refer to consists (or should consist) of
lines like:

1 2 3 4
5 6 7 8
9 10 11 12

Assuming this is the case (and that there are only the three lines
of input), the first fscanf() will apply the four "%d" directives
in turn, successfully reading and converting "1", then " 2", then
" 3", then " 4". The newline after the 4 will remain in the input
stream. The snipped code will (one hopes; I did not look) do
something useful with the four integers. The tests for feof(Fp1)
and ferror(Fp1) will produce 0, as there was no error and there is
a newline in the stream ready to read.

The next fscanf() will again apply four "%d" directives, this time
reading and converting "\n5", " 6", " 7", and " 8" respectively,
and leave a newline in the stream. The feof() and ferror() tests
will behave as before.

The third fscanf() will likewise read and convert "\n9", " 10",
" 11", and "12", and leave a newline in the stream. The feof()
and ferror() tests will once again say "no EOF encountered, nor
any error".

The fourth fscanf() call will try to apply the first %d, and will
read the newline but then encounter EOF. Having failed to perform
any conversions, fscanf() will return EOF -- if it had done at least
one successful conversion it would return a positive number -- but
its return value will be ignored. The four values left over in
the x[] array from the previous fscanf() will still be there, and
the snipped code will do something with them. This time, however,
the feof() test will return a nonzero value, so the loop will stop.

In other words, the above code will successfully read all four
lines of a three-line file.

The moral of this story, as it were, is never to use feof() to
control a loop. The fscanf() call has a return value, and you
really have to inspect it in order to write reliable code.
 
R

Régis Troadec

"Chris Torek" <[email protected]> a écrit dans le message de

Hi,
while(!feof(Fp1) ...

This is virtually *guaranteed* to be wrong (about a 99.997% chance
in my experience, and the remaining .003% are just redundant :) ).
Now, let us find out whether it is:
do {
/* Get a line with 4 integers */
fscanf(Fp1,"%d%d%d%d",&x[0],&x[1],&x[2],&x[3]);

[snippage of code that uses the values in x[]]
} while(!feof(Fp1) && !ferror(Fp1));

Yes, I don't mastering formatted I/O in C, I quickly picked out this nasty
do-while loop using feof and ferror from my C99 draft (example 3,
§7.19.6.2).

[snipped the excellent informations about fscanf]
The moral of this story, as it were, is never to use feof() to
control a loop. The fscanf() call has a return value, and you
really have to inspect it in order to write reliable code.

You're perfectly right. Here is a better version to read 4 integers per line
:

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

int main(int argc, char *argv[])
{
FILE * fp;

int arr[4], cnt;

if(argc != 2)
{
fprintf(stderr, "Usage : "
"%s <fic>\n"
"Reads four ints per line from <fic>\n",
argv[0]);
exit(EXIT_FAILURE);
}

fp = fopen(argv[1],"r");

if(fp)
{
cnt = fscanf(fp, "%d%d%d%d\n",&arr[0], &arr[1],&arr[2],&arr[3]);
while(cnt==4)
{
/* Display the picked out values*/
printf("%d %d %d %d\n",arr[0], arr[1], arr[2], arr[3]);

/* Some processings here */

/* Reads the next line */
cnt = fscanf(fp, "%d%d%d%d\n",&arr[0], &arr[1],&arr[2],&arr[3]);
}

fclose(fp);
}

return EXIT_SUCCESS;
}

Regis
 
T

those who know me have no need of my name

in comp.lang.c i read:
cnt = fscanf(fp, "%d%d%d%d\n",&arr[0], &arr[1],&arr[2],&arr[3]);
while(cnt==4)
{
/* Display the picked out values*/
printf("%d %d %d %d\n",arr[0], arr[1], arr[2], arr[3]);

/* Some processings here */

/* Reads the next line */
cnt = fscanf(fp, "%d%d%d%d\n",&arr[0], &arr[1],&arr[2],&arr[3]);
}

writing the fscanf twice is just asking for trouble, e.g., any tiny editing
mistake and they will work differently and you will probably only `see' the
first while you gnash your teeth debugging.

while (4 == (cnt = fscanf(...))
{
printf(...);
/* processing */
}
 
D

Dave Thompson

"Chris Torek" <[email protected]> a écrit dans le message de
news:[email protected]...
Yes, I don't mastering formatted I/O in C, I quickly picked out this nasty
do-while loop using feof and ferror from my C99 draft (example 3,
§7.19.6.2).
(where the last operation on the subject file in the loop is
fscanf(stdin, "%*[^\n]"), whose return value cannot usefully be
checked unlike most *scanf calls)
[snipped the excellent informations about fscanf]
The moral of this story, as it were, is never to use feof() to
control a loop. The fscanf() call has a return value, and you
really have to inspect it in order to write reliable code.

You're perfectly right. Here is a better version to read 4 integers per line
:
cnt = fscanf(fp, "%d%d%d%d\n",&arr[0], &arr[1],&arr[2],&arr[3]);
while(cnt==4)
{
cnt = fscanf(fp, "%d%d%d%d\n",&arr[0], &arr[1],&arr[2],&arr[3]);
}

Note that \n in a *scanf format string doesn't match just a newline;
like any whitespace it matches *any and all* whitespace. For input
from a file like this case it can be OK, but for interactive prompted
input it makes the program appear to "hang"; FAQ 12.17.

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,144
Latest member
KetoBaseReviews
Top