1
votes

I'm new at programming so there are some basics and maybe common sense that I don't know. I have a question about how to use fgets right. Based on the explanation of fgets, it seems that fgets should stop whenever it reads n-1 characters, hit the EOF or hit a newline character. For example, I create a text file like below:

red  100
yellow  400
blue  300
green 500
purple 1000
...

The color and the integer is separated by a tab. When I create this text file, I need to hit enter at the end of each line to start a new line. In this case, hitting enter equals to add a newline character, '\n', is that right?

If it is right that there is a '\n' at the end of each line, I run the fgets code as below:

fgets(string, 100, fp);

Since the characters contain in each line is much less than 100, the fgets should hit the newline character before reach the maxlength limit and it should stop and return a NULL. Is that correct?

If my understanding above are not right, there is no '\n' at the end of each line, or fgets does not stop at the end of each line, what is the number of maxlength (i.e., the N in the fgets(string, N, stream) function) should I pick to make sure that the file input properly due to my ultimate goal is to parsing each line and store each line into a structure. By the way, there are 100 lines in the file.

3
Your question is unclear. What do you mean "generate a .txt file"? Show some example code, break that chunk of text down into readable paragraphs, make it more accessible to us. Ask as tersely as you possibly can.cadaniluk
The number you should pick for n in fgets is the number of bytes length of the buffer. If that limit is reached before the EOL in the file, then no newline will be at the end of the input string, and the next call to fgets will continue from the same place in the file. But the question is a muddle. Output is not input.Weather Vane
@cpatricio C has strings. They are sequences of characters with a null character at the end.chux - Reinstate Monica
"What the number should I pick for n if I don't know how many characters will be included in each line?" --> As some point, robust code need to assess if it being hacked. If code imposes no limit, then a call to my_favorite_input_function() allows outside agents to overwhelm system resources. Pick a large n - suggest twice as large as suggested by the programs needs: #define LINE_SIZE 1000 or 80 or 8675309 and deem any input where (strlen(buffer) >== LINE_SIZE - 1) is true as nefarious and exit with a failure.chux - Reinstate Monica
This post has at least 5 far ranging questions. Suggest narrowing it and posting what you have attempted.chux - Reinstate Monica

3 Answers

3
votes
 #include <stdio.h>

 int main()
 {
    char str[150],str2[100][150];
    int i=0,j=0,value[100];
    FILE* fp;
    fp = fopen("file.txt", "r");
    while (fgets(str,150, fp)) {
        i++;
        printf("%3d: %s\n", i, str);
        /** if you want to split value and string*/
        sscanf(str,"%s %d",&str2[j],&value[j]);
        printf("%d %s\n",value[j],str2[j]);
        j++;
    }
    fclose(fp);
    return 0;
}

You can use sscanf() to easily split values and fgets() to read file.

2
votes
fp = fopen("sample.txt", "r");
while (1) {
        if (fgets(line,150, fp) == NULL) break;
        i++;
        printf("%3d: %s", i, line);
}
printf("%d\n",i);
1
votes
// hello.c
//
// Usage:
//
// gcc -Wall hello.c && ./a.out /tmp/somefile.txt

#include <stdlib.h>     // for perror, ...
#include <stdio.h>      // for printf, ...
#include <assert.h>     // for assert
#include <sys/time.h>   // for gettimeofday

static inline long long int nowUs () {
  long long int now;
  struct timeval timer_us;
  if (gettimeofday(&timer_us, NULL) == 0) {
    now = ((long long int) timer_us.tv_sec) * 1000000ll +
      (long long int) timer_us.tv_usec;
  }
  else now = -1ll;

  return now;
}

int main (const int argc, const char * argv[]) {
  assert(2 == argc);
  long long int started = nowUs();
  size_t count = 0;
  char msg[128], * fgets_rv;
  FILE * fp = fopen(argv[1], "r");

  while ((fgets_rv = fgets(msg, sizeof(msg), fp))) {
    assert(fgets_rv == msg);
    count++;
  }
  if (ferror(fp)) 
    perror(argv[1]);
  else if (feof(fp)) {
    printf("Read %zu lines of file '%s' in %lldµs\n", 
        count, argv[1], nowUs() - started);
  }
  else {
    printf("UNEXPECTED\n");
  }
  fclose(fp);
  return 0;
}

Sample output:

alec@mba ~/process/sandbox $ gcc -Wall hello.c && ./a.out /tmp/bigfile.t02
Read 100000 lines of file '/tmp/bigfile.t02' in 16521µs