如何扫描一个字符串,一个管道,然后另一个字符串,中间没有任何中断/空格?

时间:2017-08-11 09:23:22

标签: c string input scanf

用户将输入总线配置,如此

2
OO|XO
XX|XX

其中

  • 第一行中的数字(让 n )告诉行数,

  • 以下 n 行显示一对两个席位

  • 中间有走道,由 | 表示,是一个管道。

  • 座位可以被占用或空着。空座位用 O 表示;由 X 占据的。

char str1[3], str2[3];

我将每对座位视为一根绳子,

char pipe;

和管道作为角色。

我试过这样做:

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

和此:

scanf("%s", str1);
pipe = getchar();
scanf("%s", str2);

但仍然没有运气。

问题是:如何一次输入两个/多个字符/字符串而不用任何空格或中断分隔它们?

3 个答案:

答案 0 :(得分:2)

首先,阅读%s转换说明符的属性。输入由空格分隔,而不是由管道|分隔,至少不是自动分隔。

最简单的解决方法是使用 maximum field width ,类似

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("%2s|%2s", str1, str2);     

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

答案 1 :(得分:2)

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

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

Demo.

答案 2 :(得分:0)

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

  • 如果字符串长度是固定的,您只需指定要为%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 */
    }
    
  • 如果字符串长度是可变的,例如在某些行中具有不同座位数的平面上,则可以使用scanset %[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;
}