我的代码中有以下行:
char y[] = "a";
scanf("Letter: %s", y);
printf("%s\n", y);
第二行根本不影响第三行的输出。我已经包括在内<stdio.h>
,我想不出有什么问题......
我的代码中有以下行:
char y[] = "a";
scanf("Letter: %s", y);
printf("%s\n", y);
第二行根本不影响第三行的输出。我已经包括在内<stdio.h>
,我想不出有什么问题......
最大的错误之一是在scanf
函数中包含除格式规范(如%s
或%d
)之外的引号之间的任何字符串。代码应该是scanf("%s",y)
。如果您使用任何其他字符,那么您将不得不挠头寻找出问题。
(即使您包含任何字符,那么您也必须输入该字符,例如,如果您scanf("letter: %s",y);
在输入时写入,则必须像C:\>letter:
“您将输入的字母”一样写)这显然不是一个明智的主意。而且该scanf
功能不存在打印出来,它只是从终端读取输入。要打印出来,你应该使用printf("letter");
它。
假设您必须使用一个从两个 int 变量中获取输入,scanf()
然后您将使用 like scanf("%d%d",&a,&b);
,因为您可以看到除了引号中的格式规范外,我什么也没放。
我假设您想要一个提示,而不是格式字符串:
printf("Letter: ");
fflush(stdout);
scanf("%s", y);
请注意,您的字符串只能包含一个字符。如果输入更长的字符串,则会出现缓冲区溢出。
您还应该养成测试返回值的习惯scanf
。它返回成功读取的项目数。因此,在您的示例中,如果它读取一个字符串,它应该返回1
. 因为您没有对其进行测试,所以您花了很长时间试图找出问题所在,而实际上它会告诉您没有读取任何项目。
其他答案已正确诊断为scanf()
不输出任何数据(特别是不生成任何提示),而问题似乎期望scanf("Letter: %s", y)
输出提示Letter:
然后读取响应。scanf()
如果键入多个字符,还会出现诸如不检查返回值和缓冲区溢出等问题。
其中一个答案表明,格式字符串中不应出现转换规范以外的字符。这个答案主要是一个反例,展示了其他角色如何至关重要。您可以获取此示例代码并对其进行修改,以提高您对scanf()
函数族如何工作的理解。请注意,它不是交互式程序;它正在使用 转换数据sscanf()
,几乎就像数据已被 读取一样fgets()
。练习:为什么它只是“几乎好像”而不是简单的“好像”?
假设您正在处理一个格式为以下行的文件:
centre (23, 41) size (19, 42)
假设您要读取这四个数字,您的格式字符串可能是以下内容的变体:
"centre (%d,%d) size (%d,%d)"
这几乎是健全的。但是,该格式无法发现缺少第二个右括号。为了确保最后的括号存在,您需要一个格式字符串,如:
"centre (%d ,%d ) size (%d ,%d %1[)]"
其中空格允许输入间距的许多变化,并且扫描集 ( %1[)]
) 需要一个右括号。您将测试scanf()
返回的 5 个字段。请注意,如果您使用扫描集 ( %*1[)]
) 禁止分配,则如果括号丢失,您将不会收到错误指示。这是一个判断,您希望在您接受的有效输入方面有多灵活。
#include <stdio.h>
int main(void)
{
int x1, y1, x2, y2;
char str[10];
const char *data[] =
{
"centre ( 19, 43 ) size ( 21, 37 )",
"centre (19, 43) size (21, 37)",
"centre (19, 43) size (21, 37",
"centre(19,43) size(21,37)",
"centre(19,43) size(21,37",
"centre ( 19 , 43 ) size ( 21 , 37 )",
};
enum { NUM_DATA = sizeof(data) / sizeof(data[0]) };
const char *format5[] =
{
"centre (%d ,%d ) size (%d ,%d %[)]",
"centre (%d,%d) size (%d,%d%[)]",
};
enum { NUM_FORMAT5 = sizeof(format5) / sizeof(format5[0]) };
const char *format4[] =
{
"centre (%d ,%d ) size (%d ,%d )",
"centre (%d,%d) size (%d,%d)",
};
enum { NUM_FORMAT4 = sizeof(format4) / sizeof(format4[0]) };
printf("Format 5\n");
for (int i = 0; i < NUM_FORMAT5; i++)
{
printf("Format: <<%s>>\n", format5[i]);
for (int j = 0; j < NUM_DATA; j++)
{
int rc;
printf(" Data: <<%s>>\n", data[j]);
if ((rc = sscanf(data[j], format5[i], &x1, &y1, &x2, &y2, str)) != 5)
printf("!! Failed: scanf() returned %d\n", rc);
else
printf("== Passed: centre(%d,%d) size(%d,%d)\n", x1, y1, x2, y2);
}
}
printf("\nFormat 4\n");
for (int i = 0; i < NUM_FORMAT4; i++)
{
printf("Format: <<%s>>\n", format4[i]);
for (int j = 0; j < NUM_DATA; j++)
{
int rc;
printf(" Data: <<%s>>\n", data[j]);
if ((rc = sscanf(data[j], format4[i], &x1, &y1, &x2, &y2)) != 4)
printf("!! Failed: scanf() returned %d\n", rc);
else
printf("== Passed: centre(%d,%d) size(%d,%d)\n", x1, y1, x2, y2);
}
}
return 0;
}
Format 5
Format: <<centre (%d ,%d ) size (%d ,%d %[)]>>
Data: <<centre ( 19, 43 ) size ( 21, 37 )>>
== Passed: centre(19,43) size(21,37)
Data: <<centre (19, 43) size (21, 37)>>
== Passed: centre(19,43) size(21,37)
Data: <<centre (19, 43) size (21, 37>>
!! Failed: scanf() returned 4
Data: <<centre(19,43) size(21,37)>>
== Passed: centre(19,43) size(21,37)
Data: <<centre(19,43) size(21,37>>
!! Failed: scanf() returned 4
Data: <<centre ( 19 , 43 ) size ( 21 , 37 )>>
== Passed: centre(19,43) size(21,37)
Format: <<centre (%d,%d) size (%d,%d%[)]>>
Data: <<centre ( 19, 43 ) size ( 21, 37 )>>
!! Failed: scanf() returned 2
Data: <<centre (19, 43) size (21, 37)>>
== Passed: centre(19,43) size(21,37)
Data: <<centre (19, 43) size (21, 37>>
!! Failed: scanf() returned 4
Data: <<centre(19,43) size(21,37)>>
== Passed: centre(19,43) size(21,37)
Data: <<centre(19,43) size(21,37>>
!! Failed: scanf() returned 4
Data: <<centre ( 19 , 43 ) size ( 21 , 37 )>>
!! Failed: scanf() returned 1
Format 4
Format: <<centre (%d ,%d ) size (%d ,%d )>>
Data: <<centre ( 19, 43 ) size ( 21, 37 )>>
== Passed: centre(19,43) size(21,37)
Data: <<centre (19, 43) size (21, 37)>>
== Passed: centre(19,43) size(21,37)
Data: <<centre (19, 43) size (21, 37>>
== Passed: centre(19,43) size(21,37)
Data: <<centre(19,43) size(21,37)>>
== Passed: centre(19,43) size(21,37)
Data: <<centre(19,43) size(21,37>>
== Passed: centre(19,43) size(21,37)
Data: <<centre ( 19 , 43 ) size ( 21 , 37 )>>
== Passed: centre(19,43) size(21,37)
Format: <<centre (%d,%d) size (%d,%d)>>
Data: <<centre ( 19, 43 ) size ( 21, 37 )>>
!! Failed: scanf() returned 2
Data: <<centre (19, 43) size (21, 37)>>
== Passed: centre(19,43) size(21,37)
Data: <<centre (19, 43) size (21, 37>>
== Passed: centre(19,43) size(21,37)
Data: <<centre(19,43) size(21,37)>>
== Passed: centre(19,43) size(21,37)
Data: <<centre(19,43) size(21,37>>
== Passed: centre(19,43) size(21,37)
Data: <<centre ( 19 , 43 ) size ( 21 , 37 )>>
!! Failed: scanf() returned 1
请注意,当缺少第二个右括号时,“格式 4”下的格式字符串如何接受数据。即使缺少字符,也满足 4 个转换规范。“格式 5”格式拒绝这些数据行。
示例代码和数据没有演示它,但代码也很乐意读取多个右括号(因为它使用%[)]
)。可以通过使用%1[)]
来避免这种情况,规定最后只有一个右括号。您还可以使用%n
转换规范和第六个参数(另一个int *
)来获取处理的字符数。这将允许您检测扫描停止的位置,从而在所需的输入之后是否有未处理的字符。请注意,%n
转换规范不计入scanf()
等人的返回值中。这个片段可以粘贴在main()
代码中函数的末尾:
printf("\nFormat 6\n");
int len, rc;
const char data6[] = "centre ( 19 , 43 ) size ( 21 , 37 )))";
const char format6[] = "centre (%d ,%d ) size (%d ,%d %1[)]%n";
printf("Format: <<%s>>\n", format6);
printf(" Data: <<%s>>\n", data[5]);
if (sscanf(data6, format6, &x1, &y1, &x2, &y2, str, &len) != 5)
printf("!! Failed: scanf() returned %d\n", rc);
else
printf("== Passed: centre(%d,%d) size(%d,%d) len=%d <<%s>>\n",
x1, y1, x2, y2, len, &data6[len]);
它生成输出:
Format 6
Format: <<centre (%d ,%d ) size (%d ,%d %1[)]%n>>
Data: <<centre ( 19 , 43 ) size ( 21 , 37 )))>>
== Passed: centre(19,43) size(21,37) len=35 <<))>>
如果您了解为什么会获得每个结果,那么您对scanf()
. 如果您不确定为什么,请尝试并阅读规范(例如 POSIX sscanf()
),直到您确定您理解它为止。
在你的情况下
char y[] = "a";
scanf("Letter: %s", y);
printf("%s\n", y);
你应该像这样提供输入。
字母:abcd
它将正常工作
例如,如果 scanf 是这样写的
int y;
scanf("y=%d", &y);
那么你应该输入像
y=10
不是 10
我想你得到了你想要的...... :) 现在享受