0

It looks like the fgets() includes the newline in the return results. Can I find some command that does not include newline in the output? Also is there version of fgets() that reads all the tokens on the line and returns pointers to them?

Below code might work, but looks about 10-20% slower than fgets(). Maybe because this read the characters one by one (?)

  // Read characters from file and exclude terminating newline
  // Input argument 'size' must be integer larger than one
  char *fgetsnn(char *s0, int size, FILE *fp) {
    size--;
    char c;
    char *s=s0;
    char *se=s0+size;
    while (s<se) {
      c=fgetc(fp);
      switch (c) {
        case EOF:
          *s='\0';
          if (ferror(fp)!=0) {
            return(NULL);
          };
          if (s==s0) {
            return(NULL);
          } else {
            return(s0);
          };
        case '\n':
          *s='\0';
          return(s0);
        case '\0':
          *s='\0';
          return(NULL);
        default:
          *s=c;
          s++;
      };
    };
    *s='\0';
    return(s0);
  };

It looks like using the filebuffer in smaller pieces makes the reading slower. I guess then it would be fastest to read the whole file at once and try to split it in the memory instead (I tried, but it didn't seem help at all). The 'drawback' here is that the most likely condition - the 'default' is last in the switch (and can be only last) and thus all the different condition before default will keep slowing down the speed. Then most likely reason for speed limit is hardware (harddisc) speed.

Below case the most likely character case with normal letters is arranged 1st using if-then rather than case:

  // Read characters from file and exclude terminating newline
  // Input argument 'size' must be integer larger than one
  char *fgetsnn(char *s0, int size, FILE *fp) {
    size--;
    char c;
    char *s=s0;
    char *se=s0+size;
    while (s<se) {
      c=fgetc(fp);
      if (c>'\n') {
        *s=c;
        s++;
      } else {
        switch (c) {
          case '\n':
            *s='\0';
            return(s0);
          case EOF:
            *s='\0';
            if (ferror(fp)!=0) {
              return(NULL);
            };
            if (s==s0) {
              return(NULL);
            } else {
              return(s0);
            };
          case '\0':
            *s='\0';
            return(NULL);
          default:
           *s=c;
          s++;
        };
      };
    };
    *s='\0';
    return(s0);
  };

If the newline ascii code would be '1' it could pass fast all the case (also that are between '1' and '\n')... And maybe ascii code for ' ' (space) should be '2' and for '\t' maybe '3' to make the string separating into tokens faster also...

user1070696
  • 301
  • 2
  • 4
  • 4
    Just remove the newline manually. – Shawn Oct 05 '21 at 05:20
  • 1
    No, not a general easy to use function. However, depending on the input you want to accept `scanf` may be able to do it. That said... I still recommend `fgets` followed by code to strip newlines – Support Ukraine Oct 05 '21 at 05:23
  • " reads all the tokens on the line and returns pointers to them?" no... but maybe `scanf` with `%s` is doing what you want. It's a bit unclear what you want to do. – Support Ukraine Oct 05 '21 at 05:25
  • 2
    You say: "[R]eads all the tokens" How do you define a "token" for your specific task and use-case? – Some programmer dude Oct 05 '21 at 05:26
  • "Is there command in C-language to read line, but excluding all the newline characters?" --> Sadly, no, there is no good single function in standard C to do so. – chux - Reinstate Monica Oct 05 '21 at 08:40
  • 1
    That function have one fatal flaw which could lead to an infinite loop and buffer overflows: The [`fgetc`](https://en.cppreference.com/w/c/io/fgetc) function returns an **`int`** which is rather important to be able to compare properly to the `int` value `EOF`. – Some programmer dude Oct 05 '21 at 16:07
  • And why not simply use `fgets` and remove the newline it pus in there? As answered in the duplicate. – Some programmer dude Oct 05 '21 at 16:07

0 Answers0