【问题标题】:How to scanf until I get something not of the same form如何扫描直到我得到不同形式的东西
【发布时间】:2020-02-10 04:26:12
【问题描述】:

我正在从 Stdin 输入一个文本文件,该文件将具有不确定数量的坐标,然后是 #,然后是另一组坐标。如何将坐标扫描到一个循环中,一旦我点击 # 就停止,这将让我扫描 # 之后的其余坐标?

我尝试了几个循环,例如:

    `while(scanf("[%d,%d]\n", &x, &y) == 1){

        //do stuff//

}

但我不觉得我离答案更近了,任何帮助将不胜感激,干杯

输入示例(# 周围没有“”,但如果没有,则在此处消失):

[0,0]  
[1,1]  
[2,2]  
"#"  
[1,3]  
[3,6]  
[9,8]

【问题讨论】:

  • 发布几行输入示例(缩进 4 个空格)。有几种方法可以做到这一点,但查看输入会有所帮助。
  • 您应该测试 2,而不是 1。方括号是否在数据中?如果是这样,当输入为 # 时,您将返回零
  • 去掉'\n' 中的"[%d,%d]\n"——它并没有像你认为的那样做。在缓冲区中使用fgets,然后使用sscanf。 (否则您将需要读取并丢弃字符,直到您读取 '\n'EOF

标签: c loops scanf


【解决方案1】:

您可能希望将代码包装到 fgets(或 readline)中:。

    char buff[2048] ;
    while ( fgets(buff, sizeof(buff), stdin )) {
        // Check of 'last' marker
        if ( buff[0] == '#' ) break ;
        // Check if looks like coordinates
        if ( sscanf(buff, "[%d,%d]\n", &x, &y) == 2 ) {
             // do something
        } ;
    } ;
  • 对 sscanf 返回码(2 而不是 1)的小修复 - 检查 2 个字段的解析

【讨论】:

  • 下一条评论,'\n'"[%d,%d]\n"中的作用是什么?
【解决方案2】:

由双引号 "#" 分隔的输入数据会使问题稍微复杂化。您使用scanf 阅读的尝试注定会失败。您的scanf 格式字符串"[%d,%d]\n" 不会读取/丢弃行尾的'\n'。事实上,它根本不匹配'\n'scanf 不解释控制字符,所以格式字符串中的 '\n' 正在寻找的是一个文字 'n' 在两次转换发生后导致 input-failure。 p>

你有两个选择:

  1. 从格式字符串中删除'\n',继续使用scanf(不推荐),然后手动读取/丢弃该行中的所有剩余字符,直到达到'\n'(使用getchar() 或@987654334 @);或
  2. 使用fgets() 或POSIX getline()面向行的 输入函数将每一行读入缓冲区,以确保每次读取完整的数据行,然后解析您需要的信息从缓冲区使用sscanf(首选方法)。

采用上述首选方法,您可以执行以下操作:

#include <stdio.h>
#include <string.h>

#define MAXC 1024   /* if you need a constant, #define one (or more) */

int main (void) {

    char buf[MAXC];     /* buffer for each line */
    int x, y, n = 0;    /* coordinates & counter */

    printf ("set[%d]:", n++);                   /* initial set[]: label */
    while (fgets (buf, MAXC, stdin)) {          /* read each line */
        if (strncmp (buf, "\"#\"", 3) == 0)     /* line starts with "#"? */
            printf ("\nset[%d]:", n++);         /* output new set[]: label */
        else if (sscanf (buf, " [%d,%d]", &x, &y) == 2) /* 2 conversions? */
            printf (" %d,%d", x, y);            /* output coordinates */
    }
    putchar ('\n');     /* tidy up with newline */

    return 0;
}

注意:如果您的文件只包含# 而不是"#",您可以简单地检查缓冲区中的第一个字符而不是使用strncmp

输入文件示例

$ cat dat/coordgroups.txt
[0,0]
[1,1]
[2,2]
"#"
[1,3]
[3,6]
[9,8]

使用/输出示例

$ ./bin/readcoords < dat/coordgroups.txt
set[0]: 0,0 1,1 2,2
set[1]: 1,3 3,6 9,8

检查一下,如果您还有其他问题,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-30
    • 2020-05-30
    • 1970-01-01
    • 2016-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多