0

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" enter image description here

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;
}
4
  • 2
    Why are you calling fseek in the loop? The read position will be advanced automatically when you read from the file. Commented Sep 6, 2022 at 11:45
  • Why not test if fread actually read the bytes you asked it to... Maybe at EOF it stopped reading, until you had fseek try to go beyond the end of the file.... Weird... Commented Sep 6, 2022 at 11:48
  • 1
    No problem if you replace the unnecessary while(fseek... and fread with while (fread(&ch, sizeof(double), 1, fp) == 1) Commented Sep 6, 2022 at 11:59
  • 1
    check return values from fopen, fwrite, fread Commented Sep 6, 2022 at 12:03

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.