【问题标题】:parsing string off a configuration using strtok in C在 C 中使用 strtok 解析字符串
【发布时间】:2010-06-17 18:45:16
【问题描述】:

在配置文件中我有类似的条目:

文件路径 = c:\Program Files\某个值

路径可以包含空格并且该字符串上没有引号。我尝试用 strtok 解析这个:

char *option;
char *value;

value = strtok(line, " =");
strcpy(option, value);
value = strtok(NULL, " =");

其中 line 是我从文件中读取的行,选项将包含等号的左侧(文件路径),值将包含右侧(c:\program files\some value)。 我知道,这是糟糕的编码,但我还没有找到更好的东西。对不起... 无论如何,对于那些右侧没有空格的选项,它的效果很好,但在那些包含空格的选项中,它只返回字符串直到第一个空格:c:\Program。

还有其他方法吗?

感谢代码。 杰西卡

【问题讨论】:

  • strtok 的第二个参数给出了多个分隔符,每个分隔符将分割字符串。所以“=”将在空格或等号上分割。

标签: c string parsing


【解决方案1】:

去掉分隔符中的空格:

value = strtok(line, "=");

【讨论】:

  • 哎呀,对不起。它在其他地方崩溃了。
【解决方案2】:

这里: strtok(line, " =")

你是说在空间和 = 上分割。如果需要,可以减少空间并修剪结果。

【讨论】:

    【解决方案3】:

    您可以使用strtok_r(),并将它提供给您的指针用于字符串的其余部分。

    char *rightside;
    char *leftside;
    
    leftside = strtok_r(line, "=", &rightside);
    

    请注意,这会破坏您的“行”缓冲区,但通常情况下,如果您只是将新数据读入其中,这没什么大不了的。

    【讨论】:

      【解决方案4】:

      使用sscanf():

      char * conf = "filepath = c:\\Program Files\\some value";
      char key[20];
      char value[40];
      sscanf(conf, "%s = %40c", key, value);
      printf("key: %s value: %s\n", key, value); 
      

      【讨论】:

      【解决方案5】:

      应该这样做:

      #include <stdlib.h>
      #include <stdio.h>
      
      #define INPUT_FILE "test.txt"
      #define BUF_SIZE 1024
      #define SEP " = "
      
      #define CHECK(x) \
          do { \
              if (!(x)) { \
                  fprintf(stderr, "%s:%d: ", __func__, __LINE__); \
                  perror(#x); \
                  exit(-1); \
              } \
          } while (0) \
      
      void trim(char *s) {
          // Trim spaces and tabs from beginning:
          int i = 0, j;
          while((s[i]==' ') || (s[i]=='\t')) {
              i++;
          }
          if(i > 0) {
              for(j = 0; j < strlen(s); j++) {
                  s[j] = s[j+i];
              }
          s[j] = '\0';
          }
      
          // Trim spaces and tabs from end:
          i = strlen(s) - 1;
          while((s[i]==' ') || (s[i]=='\t') || (s[i]=='\r')  || (s[i]=='\n')) {
              i--;
          }
          if(i < (strlen(s) - 1)) {
              s[i+1] = '\0';
          }
      }
      
      int main() {
          FILE *f;
          char line[BUF_SIZE + 1];
          char *opt, *val;
      
          line[BUF_SIZE] = '\0';
      
          f = fopen(INPUT_FILE, "rt");
          CHECK(f != NULL);
      
          while (NULL != fgets(line, sizeof(line), f)) {
              printf("%s", line);
      
              opt = strstr(line, SEP);
              if (!opt) {
                  continue;
              }
      
              *opt = '\0';
              val = opt + strlen(SEP);
              opt = line;
      
              trim(opt);
              trim(val);
      
              printf("opt=<%s> val=<%s>\n", opt, val);
          }
          fclose (f);
      
          return 0;
      }
      

      trim 函数取自 here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多