1

Here's my code and output of my variables: What else do I need to add to my while loop so that I can have my variables and methods work.

int main() {
  FILE *ifp;
  ifp = fopen("processes.txt","r");
  if(ifp == NULL) {
      printf("Error Opening file.\n");
      exit(1);
  }

  char str[100];
  int i=0;

  while(fgets(str, 100, ifp) != NULL) {
    fscanf(ifp," %d %0.1f %d %d", &arr[i].pid, &arr[i].AT, &arr[i].duration, &arr[i].rank);
    i++;
  }
}
printf("ProceId AT   duration rank\n");

for (int j = 0; j < i - 1; ++j){
    printf("%d\t%0.1f\t%d\t%d\n",arr[j].pid,arr[j].AT,arr[j].duration,arr[j].rank );
}


ProceId AT   duration rank
1398    0.0     0       0
2306    0.0     0       0
3219    0.0     0       0
4478    0.0     0       0
5653    0.0     0       0
6399    0.0     0       0
7777    0.0     0       0

Here is the file which has a line of strings that i don't need which is why i used fgets.

ProcessID   ArrTime Duration  Rank

1398        1.0     16      3
2306        4.5     6       7
3219        3.0     11      1
4478        2.0     3       5
5653        3.5     7       2
6399        4.0     8       6
7777        2.5     17      8   
  • Well, we can't see how you're printing them, so a [mcve] would help quite a bit. It's unclear why you're using `fgets` and `fscanf`, are you intending to only read from every other line? Maybe you meant to just use `fscanf` or perhaps `sscanf` on each line you get from `fgets`? You should also always check the return value from the scanf functions to make sure they actually parsed the correct number of items. – Retired Ninja Dec 02 '18 at 20:21
  • The `while(fgets` is questionable, (you try to discard a line ever loop iteration), it would be clearer code to just discard the first line of the file and then not call `fgets` again. It would also be good to check the return value of `fscanf` so that you can report an error if something goes wrong, instead of saving garbage values – M.M Dec 02 '18 at 22:04

1 Answers1

0

Change this:

fscanf(ifp," %d %0.1f %d %d", &arr[i].pid, &arr[i].AT, &arr[i].duration, &arr[i].rank);

to this:

fscanf(ifp," %d %f %d %d", &arr[i].pid, &arr[i].AT, &arr[i].duration, &arr[i].rank);

since you were using an invalid conversion specifier.

Pay attention to the compiler warnings next time, they usually tell the whole story:

warning: invalid conversion specifier '.'
      [-Wformat-invalid-specifier]
        fscanf(ifp," %d %0.1f %d %d", &arr[i].pid, &arr[i].AT, &arr[i].d...
                       ~~~^
warning: format specifies type 'int *' but the argument has type
      'float *' [-Wformat]
        fscanf(ifp," %d %0.1f %d %d", &arr[i].pid, &arr[i].AT, &arr[i].d...
                              ~~                   ^~~~~~~~~~
                              %f
warning: data argument not used by format string
      [-Wformat-extra-args]
  ..." %d %0.1f %d %d", &arr[i].pid, &arr[i].AT, &arr[i].duration, &arr[i].ra...
     ~~~~~~~~~~~~~~~~~                                             ^

The warnings suggest that because of the invalid conversion specifier, the %d format specifier is used for the float field of your struct (named AT), and then everything becomes a mess, since you are short by one format specifier...

Read more in How to only accept a certain precision (so many decimals places) in scanf?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • Wow, thank you, I didn't have any compilation warnings, I can't believe that was the one thing I needed to change to get it to work correctly. Thanks again. – The Trillest Programmer Dec 02 '18 at 20:40
  • Clang gave me the warnings without any flag @TheTrillestProgrammer. Maybe you are using GCC. Try compiling with `-Wall` flag. Glad I helped. – gsamaras Dec 02 '18 at 20:46