0

My goal is to read in a txt file (small_ramp.txt) then input all the numbers excluding the first into an array.The file has 11 lines of numbers on it, the number 10 on the first line indicating how many numbers are in the file then a following 10 numbers (1-10)Small_ramp.txt. When in command prompt i enter in Stats.exe < small_ramp.txt when executing this command I Error receive this error message.

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

int main(int argc, char* argv[])
{
    int n, i;
    FILE* fpointer;
    double *arr;

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

    if (argc != 2) {
        printf("ERROR: you must specify file name!\n");
        return 1;
    }

    if (!fpointer) {
        perror("File open error!\n");
        return 1;
    }

    fscanf(fpointer, "%d", n);// Scan first line of small_ramp.txt to find array size
    arr = (double*)malloc(sizeof(double) * n);// allocate memory for array with the size given (n)

    while (!feof(fpointer)) {
        fscanf(fpointer, "%lf", arr + 1);
    }

    for (int i = 0; i < n; ++i)
    {
        printf("%lf,", arr[i]);
    }

    fclose(fpointer);
    return 0;
}

I guess my question is am I reading in the file correctly and if so could someone point me in the right direction for fixing this error?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Maxium
  • 1
  • 1
  • 4
    `Stats.exe small_ramp.txt` instead of `Stats.exe < small_ramp.txt` – BLUEPIXY Feb 26 '16 at 06:07
  • 1
    also `while (!feof(fpointer)) { fscanf(fpointer, "%lf", arr + 1); }` --> `for(i = 0; i < n && fscanf(fpointer, "%lf", arr + i) == 1; ++i) ;` – BLUEPIXY Feb 26 '16 at 06:10
  • @JafferWilson That questions issue was he had his file name set to argv[0] instead of 1 – Maxium Feb 26 '16 at 06:13
  • Do yourself a favor and don't use `scanf`. Use `getline` or `fgets` and then parse the line as a string. To find out why, [search on this site for "scanf"](https://stackoverflow.com/search?q=scanf). – Schwern Feb 26 '16 at 06:15
  • A flexible way to provide a filename as an argument (and read from `stdin` by default) is to use a ternary operator in conjunction with your `FILE *` declaration. e.g. `FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;` You can test before closing the file with `if (fp != stdin) fclose (fp);` – David C. Rankin Feb 26 '16 at 06:17
  • 1
    See [`while (!feof(file))` is always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) for reasons why your reading loop is wrong. The [comment](https://stackoverflow.com/questions/35644664/c-how-to-read-in-a-file-from-command-line-args#comment58970114_35644664) by [BluePixy](https://stackoverflow.com/users/971127/bluepixy) also covers this issue. – Jonathan Leffler Feb 26 '16 at 06:28

1 Answers1

1
  • You have to check the number of arguments before using argv[1].
  • Passing data having wrong type to fscanf() invokes undefined behavior. Use fscanf(fpointer, "%d", &n); instead of fscanf(fpointer, "%d", n);.
  • You are reading data to only arr[1]. Therefore, arr[0] has indeterminate value and using the value invokes undefined behavior.
  • %f should be used instead of %lf to print double value via printf().

Note: They say you shouldn't cast the result of malloc() in C.

Community
  • 1
  • 1
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • 1
    `%lf` is redundant, but it's not harmful. – Schwern Feb 26 '16 at 06:21
  • May i ask why i am only reading data to arr[1]? wouldn't arr have a default position at arr[0] ? also my while loop should read in data from the entire file meaning that arr will increment by 1 each time. – Maxium Feb 26 '16 at 06:26
  • you do: fscanf(fpointer, "%lf", arr + 1);. arr + 1 is an equivalent of arr[1]. You don't use anything to index over the entire array. Also your code is additionally wrong for trusting the number of arguments found in the header of the file. You should check if the number looks sane, read up to that many entries and error out if the end of the file was not reached. –  Feb 26 '16 at 06:33
  • 1
    @employeeofthemonth `arr + 1` is equivalent to `&arr[1]`, not `arr[1]`. – MikeCAT Feb 26 '16 at 06:36
  • Yes, but that's clearly a typo, given the context. –  Feb 26 '16 at 07:37