scanf不打印或读取任何内容

时间:2013-06-19 03:50:24

标签: c

我的代码中有以下行:

char y[] = "a";
scanf("Letter: %s", y);
printf("%s\n", y);

第二行根本不会影响第三行的输出。我已经包含<stdio.h>,我想不出有什么问题......

4 个答案:

答案 0 :(得分:8)

其中一个最大的错误是在scanf函数中包含除格式规范之外的引号之间的任何字符串(例如%s或{{1}代码应该是%d。如果你采取任何其他角色,那么你将不得不挠头寻找问题。

(即使您包含任何字符,您也必须输入该字符,例如 - 如果您编写scanf("%s",y)然后输入,则必须写入scanf("letter: %s",y); “字母,您将输入该字母“)这显然不是一个明智的想法。而C:\>letter:函数不是打印出来的东西,只是为了从终端读取输入。要打印出来,你应该使用scanf就是这样。

假设您必须使用一个printf("letter");从两个int变量中获取输入,那么您将使用类似scanf(),因为您可以看到除了引号中的格式规范之外什么都没有。

答案 1 :(得分:2)

我假设你想要一个提示,而不是一个格式字符串:

printf("Letter: ");
fflush(stdout);
scanf("%s", y);

请注意,你的字符串只能容纳一个字符。如果输入更长的字符串,则会出现缓冲区溢出。

您还应养成测试scanf的返回值的习惯。它返回成功读取的项目数。因此,在您的示例中,如果它读取字符串,则应返回1。因为你没有对它进行测试,所以你花了很多时间试图弄清楚什么是错的,而实际上它会告诉你没有读过任何物品。

答案 2 :(得分:1)

其他答案已正确诊断scanf()未输出任何数据(特别是不会生成任何提示),而问题似乎预计scanf("Letter: %s", y)将输出提示{{ 1}}然后阅读回复。如果输入了多个字符,还有一些问题,例如没有检查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[)]返回的5个字段。请注意,如果使用扫描集(scanf())抑制了赋值,则如果缺少括号,则不会出现错误指示。这是一个判断调用,关于你希望在你接受的有效输入中有多灵活。

代码

%*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;
}

请注意,当缺少第二个右括号时,“格式4”下的格式字符串如何接受数据。即使缺少该字符,也满足4个转换规范。 '格式5'格式拒绝这些数据行。

示例代码和数据没有演示它,但代码也很乐意读取多个紧密括号(因为它使用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 )。通过使用%[)]来规定最后只有一个紧密括号,可以避免这种情况。您还可以使用%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 <<))>> 有一个很好的理解。如果您不确定原因,请尝试并阅读规范(例如POSIX sscanf()),直到您确定理解它为止。

答案 3 :(得分:0)

在你的案例中

char y[] = "a";
scanf("Letter: %s", y);
printf("%s\n", y);

您应该提供这样的输入。

信:abcd

它会正常工作

例如,如果scanf是这样写的

int y;
scanf("y=%d", &y);

然后你应该给出像

这样的输入

<强> Y = 10

不 10

我想你得到了你想要的...... :)现在享受