【问题标题】:Analyzing Strings with sscanf使用 sscanf 分析字符串
【发布时间】:2016-06-08 10:40:53
【问题描述】:

我需要用fgets分析一个字符串previous reader,

然后我有一行来自:

name age steps\n
mario 10 1 2 3 4\n
joe   15 3 5\n
max   20 9 3 2 4 5\n

每列有可变数量的步骤, 然后我可以阅读姓名和年龄

 sscanf(mystring, "%s %d", name, &age);

在此之后,我有一个用于读取所有步骤的 for 循环

   int step[20];
   int index=0;
   while(sscanf(mystring,"%d", &step[index++])>0);

但是这个循环永远不会结束用年龄列填充所有数组数据。

【问题讨论】:

  • 我猜while 循环将结束,因为它会读取名称并且无法将其解释为数字。请发帖minimal reproducible example
  • 你一遍又一遍地阅读相同的字符串......你期望什么
  • 您总是在扫描相同的字符串,您需要将传递给sscanf的字符串提前;只需使用strtok,如 terence hill 的答案所示。
  • "我需要分析一个字符串" --> 这通常会导致一个问题:代码是否应该检测到意外的字符串,例如“dan 1 2 3 x”或“joe bob 1 2 3”?还是您只是想要一个假设字符串中的数据格式正确的答案?
  • @RahulSinha:如果您要每小时编辑 10 个或更多帖子,最好确保您的编辑是重要的,而不是微不足道的。

标签: c


【解决方案1】:

这永远不会结束的原因是因为您不断地提供相同的字符串进行扫描。

这会起作用的:

int step[20];
int index=0;
int readLen;
while(sscanf(mystring,"%d%n", &step[index++], &readLen)>0) {
  mystring += readLen;
}

【讨论】:

    【解决方案2】:

    sokkyoku 的回答中给出了一个可行的解决方案。

    另一种读取可变长度行的可能性是使用 strtok,如以下代码 sn-p:

    int getlines (FILE *fin)
    {
        int  nlines = 0;
        int  count  = 0;
        char line[BUFFSIZE]={0};
        char *p;
    
        if(NULL == fgets(buff, BUFFSIZE, fin))
            return -1;
    
        while(fgets(line, BUFFSIZE, fin) != NULL) {
            //Remove the '\n' or '\r' character
            line[strcspn(line, "\r\n")] = 0;
            count = 0;
            printf("line[%d] = %s\n", nlines, line);
            for(p = line; (p = strtok(p, " \t")) != NULL; p = NULL) {
                printf("%s ", p);
                ++count;
            }
            printf("\n\n");
            ++nlines;
        }
    
        return nlines;
    }
    

    解释上述函数getlines

    文件fin 中的每一行都使用fgets 读取并存储在变量line 中。 然后提取line 中的每个子字符串(由空格或\t 字符分隔),并通过for 循环中的函数strtok 将指向该子字符串的指针存储在p 中(参见例如this post 更多关于 strtok 的示例)。

    然后该函数只打印p,但您可以在此处使用子字符串执行所有操作。 我还计算 (++count) 在每行中找到的项目数。最后,函数getline计算并返回读取的行数。

    【讨论】:

    • 次要位:1) 为什么'\n'strtok(p, " \t\n") 中? line[strcspn(line, "\r\n")] = 0; 确保不再有 '\n'。 2)“由空格或\t \n 字符分隔”实际上是“由空格或\t \n 字符分隔”。
    • @chux 谢谢,我后来添加了line[strcspn(line, "\r\n")] = 0 并没有修改strtok
    猜你喜欢
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多