read consecutive tabs as empty field fscanf

后端 未结 2 600
花落未央
花落未央 2021-01-24 23:06

I have a file that has certain fields separated by tabs. There will always be 12 tabs in a line, certain tabs are consecutive which indicates an empty field. I wanna use fscanf

2条回答
  •  一生所求
    2021-01-24 23:49

    I wanna use fscanf to read consecutive tabs as empty fields and store them in a structure.

    Ideally, code should read a line, as with fgets() and then parse the string.

    Yet staying with fscanf(), this can be done in a loop.


    The main idea is to use "%[^/t/n]" to read one token. If the next character is a '\t', then the return value will not be 1. Test for that. A width limit is wise.

    Then read the separator and look for tab, end-of-line or if end-of-file/error occurred.

    #define TABS_PER_LINE 12
    #define TOKENS_PER_LINE (TABS_PER_LINE + 1)
    #define TOKEN_SIZE 100
    #define TOKEN_FMT_N "99"
    
    int fread_tab_delimited_line(FILE *istream, int n, char token[n][TOKEN_SIZE]) {
      for (int i = 0; i < n; i++) {
        int token_count = fscanf(istream, "%" TOKEN_FMT_N "[^\t\n]", token[i]);
        if (token_count != 1) {
          token[i][0] = '\0';  // Empty token
        }
        char separator;
        int term_count = fscanf(istream, "%c", &separator);  // fgetc() makes more sense here
        // if end-of-file or end-of-line
        if (term_count != 1 || separator == '\n') {
          if (i == 0 && token_count != 1 && term_count != 1) {
            return 0;
          }
          return i + 1;
        }
        if (separator != '\t') {
          return -1;  // Token too long
        }
      }
      return -1;  // Token too many tokens found
    }
    

    Sample driving code

    void test_tab_delimited_line(FILE *istream) {
      char token[TOKENS_PER_LINE][TOKEN_SIZE];
      long long line_count = 0;
      int token_count;
      while ((token_count = fread_tab_delimited_line(istream, TOKENS_PER_LINE, token)) > 0) {
        printf("Line %lld\n", ++line_count);
        for (int i = 0; i < token_count; i++) {
          printf("%d: <%s>\n", i, token[i]);
        }
      } while (token_count > 0);
      if (token_count < 0) {
        puts("Trouble reading any tokens.");
      }
    }
    

提交回复
热议问题