首页 > 解决方案 > 如何使用 scanf 获取特定格式的用户输入?

问题描述

假设我想以这种形式获得用户输入,并且每一行都将定义为我的不同结构对象。我的 input.txt 文件的输入格式:

3 // number of lines
1 2 3 (4/5) 6 7
34 58 6 (23/12) 442 12
14 85 13 (43/12) 98 67

我想将 1 到 7 的每个整数分配给我的对象值,这些值在结构中定义,比如说。

我尝试过这样的scanf,但似乎不起作用;

for (int i=0;i<3;i++)
    scanf("%d %d %d (%d/%d) %d %d", &a,&b,&c,&d,&e,&f,&g);

标签: cstringscanf

解决方案


除了未能检查退货之外,您显示的代码段没有任何问题scanf()。更好的方法是将每一行读入一个足够大的字符数组,然后使用分隔整数,sscanf()以便每次使用一行输入。

否则,scanf()如果文件中存在单一格式失败,则您的输入从匹配失败的那一刻起就被破坏了。使用fgets()然后sscanf()将读取和转换解耦,因此最多单行中的格式失败只会导致该行数据的丢失。输入流中剩余的内容不依赖于转换。

解决该问题的一个简短示例是:

#include <stdio.h>

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

typedef struct {                        /* guess at your struct */
    int i1, i2, i3, i4, i5, i6, i7;
} numbers;

int main (int argc, char **argv) {
    
    char buf[MAXC];                     /* buffer to hold each line */
    int n = 0, nlines;                  /* counter and 1st line variable */
    numbers no = { .i1 = 0 };           /* struct initialized all zero */
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }
    
    if (!fgets (buf, MAXC, fp))                 /* read 1st line */
        return 1;
    if (sscanf (buf, "%d", &nlines) != 1) {     /* convert/validate nlines */
        fputs ("error: invalid 1st line format.\n", stderr);
        return 1;
    }
    /* read each line that follows up to nlines */
    while (n < nlines && fgets (buf, MAXC, fp)) { 
        /* convert & validate each integer saving in struct */
        if (sscanf (buf, "%d %d %d (%d /%d ) %d %d", &no.i1, &no.i2, &no.i3,
                    &no.i4, &no.i5, &no.i6, &no.i7) == 7)
            /* output results */
            printf ("\nstruct values:\n%4d %4d %4d %4d %4d %4d %4d\n",
                    no.i1, no.i2, no.i3, no.i4, no.i5, no.i6, no.i7);
        n++;
    }
    
    if (fp != stdin)   /* close file if not stdin */
        fclose (fp);
}

示例输入文件

$ cat dat/read7int_struct.txt
3 // number of lines
1 2 3 (4/5) 6 7
34 58 6 (23/12) 442 12
14 85 13 (43/12) 98 67

示例使用/输出

读取重定向的值stdin

$ ./bin/read7int_struct < dat/read7int_struct.txt

struct values:
   1    2    3    4    5    6    7

struct values:
  34   58    6   23   12  442   12

struct values:
  14   85   13   43   12   98   67

如果您还有其他问题,请仔细查看并告诉我。


推荐阅读