I do exercice of 'c primer plus' chapter 13.10-4: Write a program that accepts no or one command line argument. If there is one, interpret it as a filename; if there is no argument, use standard input (stdin) as input. Assume the input is a floating point number. The program is to calculate and report the arithmetic mean of the entered numbers.
result
The part of standard input can work well when excecute visual studio, but when write and read the file with cmd, average value is "nan"
enviroment
I use win10, le latest version of Visual Studio
code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[])
{
double ch;
double numbers[12];
FILE* fp;
double average=0;
int i = 0;
if (argc==1)
{
printf("enter double, end with q\n");
while (scanf_s("%lf", &ch))
{
average = ch;
printf("%lf\n", ch);
i ;
}
}
else
{
for (int j = 0; j < 12; j )
numbers[j] = 10.1 * j;
fopen_s(&fp, argv[1], "wb");
fwrite(numbers, sizeof(double), 10, fp);
fclose(fp);
if ((fopen_s(&fp, argv[1], "rb")!=0))
{
fprintf(stdout,"cant find %s\n", argv[1]);
exit(EXIT_FAILURE);
}
while (fseek(fp, (long)i * sizeof(double), SEEK_SET)!=0)
{
fread(&ch, sizeof(double), 1, fp);
fprintf(stdout, "ch\n");
average = ch;
i ;
}
fclose(fp);
}
printf("average is %lf\n", average/i);
return 0;
}
CodePudding user response:
You are using the wrong test for fseek()
with
while (fseek(fp, (long)i * sizeof(double), SEEK_SET)!=0)
The man page states
Return Value.
If successful,fseek
and_fseeki64
returns 0.
But even if you change !=0
to ==0
it is still wrong, because the man page also says
The pointer can also be positioned beyond the end of the file.
Because file reads are sequential, you can simplify the loop to
while (fread(&ch, sizeof(double), 1, fp) == 1)
{
fprintf(stdout, "ch\n");
average = ch;
i ;
}
You also omitted the essential check for file input: the return value from fread()
was ignored.