C 如何扫描一根管柱、一根管道,然后扫描另一根管柱,且其间没有任何中断/间隙?

C 如何扫描一根管柱、一根管道,然后扫描另一根管柱,且其间没有任何中断/间隙?,c,string,input,scanf,C,String,Input,Scanf,用户将输入总线的配置,如下所示 2 OO|XO XX|XX 在哪里 第一行中的数字(让n)表示行数,以及 以下n行显示了一对两个座椅 中间有一条走道,用|表示,是一条管道 座位可以是有人坐的,也可以是空的。空座位用O表示;被X占据的一个 我把每一对座位当作一根绳子 char pipe; 把烟斗当作一个角色 我试着这样做: scanf("%s %*c %s", str1, pipe, str2); 这是: scanf("%s", str1); pipe = getchar(); sca

用户将输入总线的配置,如下所示

2
OO|XO
XX|XX
在哪里

  • 第一行中的数字(让n)表示行数,以及

  • 以下n行显示了一对两个座椅

  • 中间有一条走道,用
    |
    表示,是一条管道

  • 座位可以是有人坐的,也可以是空的。空座位用O表示;被X占据的一个


我把每一对座位当作一根绳子

char pipe;
把烟斗当作一个角色

我试着这样做:

scanf("%s %*c %s", str1, pipe, str2);
这是:

scanf("%s", str1);
pipe = getchar();
scanf("%s", str2);
但还是没有运气


问题是:如何一次输入两个/多个字符/字符串而不使用任何空格或分隔符?首先,阅读
%s
转换说明符的属性。输入由空格分隔,而不是由管道分隔,至少不会自动分隔

最简单的解决方法是使用,例如

scanf("%2s%*c%2s", str1, str2);  // the * in %*<CS> indicates assignment suppression,
                                 // you don't need a corresponding argument at all, and
                                 // a wrong one will cause trouble

注意-永远不要忘记检查
scanf()的返回值
,以确保成功。

scanf
允许您指定要使用的任何分隔符,包括管道。由于管道始终存在,您不需要将其扫描到程序中,而是指示
scanf
跳过它:

char a[3], b[3];
scanf("%2s|%2s", a, b);
printf("'%s' '%s'", a, b);

有两种不同的方法来解决您的问题:

  • 如果字符串长度是固定的,您可以指定
    %s
    要读取的最大字符数,然后使用此代码:

    char str1[3], str2[3];
    if (scanf("%2s|%2s", str1, str2) == 2) {
        /* read 2 characters into str1, a pipe and 1 or 2 characters into str2 */
    }
    
  • 如果字符串长度是可变的,例如在某些行中具有不同座位数的平面上,则可以使用扫描集
    %[OX]
    ,还可以指定要读取的字符数,以防止意外输入时潜在的缓冲区溢出。以下是一个例子:

    char str1[5], str2[5];  // handle up to 4 seats on each side */
    if (scanf("%4[OX]|%4[OX]", str1, str2) == 2) {
        /* read a group of 1 to 4 `X` or `O` into str1 and str2, separated by | */
    }
    
    #include <stdio.h>
    
    int main(void) {
        char buf[128];
        int i, n, c;
        char left[3], right[3];
    
        if (fgets(buf, sizeof buf, stdin) == NULL) {
            fprintf(stderr, "invalid format, empty file\n");
            return 1;
        }
        if (sscanf(buf, "%d %c", &n, &c) != 1 || n < 0) {
            fprintf(stderr, "invalid format, expected positive number: %s\n", buf);
            return 1;
        }
        for (i = 0; i < n; i++) {
            if (fgets(buf, sizeof buf, stdin) == NULL) {
                fprintf(stderr, "missing %d lines\n", n - i);
                return 1;
            }
            if (sscanf(buf, "%2[XO]|%2[XO] %c", left, right, &c) != 2) {
                fprintf(stderr, "invalid format: %s\n", buf);
                return 1;
            } else {
                printf("row %d: %s | %s\n", i + 1 + (i >= 12), left, right);
            }
        }
        return 0;
    }
    
您可以添加另一个转换,以进一步验证该行是否具有预期的格式。以下是一个例子:

char str1[5], str2[5];  // handle up to 4 seats on each side */
if (scanf("%4[OX]|%4[OX]", str1, str2) == 2) {
    /* read a group of 1 to 4 `X` or `O` into str1 and str2, separated by | */
}
#include <stdio.h>

int main(void) {
    char buf[128];
    int i, n, c;
    char left[3], right[3];

    if (fgets(buf, sizeof buf, stdin) == NULL) {
        fprintf(stderr, "invalid format, empty file\n");
        return 1;
    }
    if (sscanf(buf, "%d %c", &n, &c) != 1 || n < 0) {
        fprintf(stderr, "invalid format, expected positive number: %s\n", buf);
        return 1;
    }
    for (i = 0; i < n; i++) {
        if (fgets(buf, sizeof buf, stdin) == NULL) {
            fprintf(stderr, "missing %d lines\n", n - i);
            return 1;
        }
        if (sscanf(buf, "%2[XO]|%2[XO] %c", left, right, &c) != 2) {
            fprintf(stderr, "invalid format: %s\n", buf);
            return 1;
        } else {
            printf("row %d: %s | %s\n", i + 1 + (i >= 12), left, right);
        }
    }
    return 0;
}
#包括
内部主(空){
char-buf[128];
inti,n,c;
字符左[3],右[3];
if(fgets(buf,sizeof buf,stdin)=NULL){
fprintf(stderr,“无效格式,空文件”);
返回1;
}
如果(sscanf(buf,%d%c,&n,&c)!=1 | n<0){
fprintf(stderr,“格式无效,应为正数:%s\n”,buf);
返回1;
}
对于(i=0;i=12),左,右);
}
}
返回0;
}

使用最大字段宽度。
“%s”
格式读取空格分隔的字符串。由于输入中没有空格,因此第一个
“%s”
读取所有行。