用户将输入总线配置,如此
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);
但仍然没有运气。
问题是:如何一次输入两个/多个字符/字符串而不用任何空格或中断分隔它们?
答案 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);
答案 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;
}