scanf 和 fgets 的问题

发布于 2024-10-16 12:07:11 字数 1364 浏览 2 评论 0原文

这是一项家庭作业,用于对某些给定的字符串进行排序。我提示用户输入他们想要使用 scanf 排序的字符串数量,根据该数字分配一个数组,然后使用 fgets 获取字符串本身。

如果字符串的数量是硬编码的,那么一切都会正常工作,但是添加 scanf 让用户决定会把事情搞砸。代码如下:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#define LENGTH  20 // Maximum string length.

int main(void)
{
    int index, numStrings = 0;
    char **stringArray;
    printf("Input the number of strings that you'd like to sort: ");
    assert(scanf("%d", &numStrings) == 1);
    stringArray = (char **)malloc(numStrings * sizeof(char *));

    for (index = 0; index < numStrings; index++)
    {
        stringArray[index] = (char *)malloc(LENGTH * sizeof(char));
        assert(stringArray[index] != NULL);
        printf("Input string: ");
        assert(fgets(stringArray[index], LENGTH, stdin) != NULL);
    }

    // Sort strings, free allocated memory.

    return 0;
}

控制台如下所示:

Input the number of strings that you'd like to sort: 3
Input string: Input string: foo
Input string: bar

它跳过循环的第一次迭代,导致数组开头出现空字符串。我的问题是,为什么会这样,我该如何解决它?


以下是将格式字符串 "%d\n" 传递给 scanf 时控制台的外观:

Input the number of strings that you'd like to sort: 3
foo
Input string: Input string: bar
Input string: baz

因此,我可以输入所有字符串,但第一次提示输入字符串是在错误的地方。

This is for a homework assignment to sort some given strings. I'm prompting the user for the number of strings they'd like to sort with scanf, allocating an array based on that number, and then getting the strings themselves with fgets.

Everything works fine if the number of strings is hardcoded, but the addition of scanf to let the user decide screws things up. Here's the code:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#define LENGTH  20 // Maximum string length.

int main(void)
{
    int index, numStrings = 0;
    char **stringArray;
    printf("Input the number of strings that you'd like to sort: ");
    assert(scanf("%d", &numStrings) == 1);
    stringArray = (char **)malloc(numStrings * sizeof(char *));

    for (index = 0; index < numStrings; index++)
    {
        stringArray[index] = (char *)malloc(LENGTH * sizeof(char));
        assert(stringArray[index] != NULL);
        printf("Input string: ");
        assert(fgets(stringArray[index], LENGTH, stdin) != NULL);
    }

    // Sort strings, free allocated memory.

    return 0;
}

And here's what the console looks like:

Input the number of strings that you'd like to sort: 3
Input string: Input string: foo
Input string: bar

It skips over the first iteration of the loop, resulting in an empty string at the beginning of the array. My question is, why does it do that, and how can I fix it?


Here's what the console looks with the format string "%d\n" passed to scanf:

Input the number of strings that you'd like to sort: 3
foo
Input string: Input string: bar
Input string: baz

So, I can input all of the strings, but the first prompt for a string is in the wrong place.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

神仙妹妹 2024-10-23 12:07:11

您必须告诉 scanf 通过将 \n 放入 scanf 中来破坏 \n:

scanf("%d\n", &numStrings)

如果没有它,scanf 将读取剩余的换行符 [从按下 Enter 按钮时开始] 作为循环中的第一行

You have to tell scanf to clobber the \n by putting \n in the scanf:

scanf("%d\n", &numStrings)

without it, scanf will read the residual newline character [from when the enter button was hit] as the first line in the loop

别闹i 2024-10-23 12:07:11

真正的答案(以我谦虚但非常正确的观点:P)不是使用 scanf。使用fgets 读取第一行(即数字),然后使用sscanfstrtoul 自行解析该字符串。这样,当有人没有以良好的格式输入数据时,您就能够处理错误,并且您不必解决 scanf 缺乏强大的空白处理的问题。

另外,永远不要使用 int 来存储大小,除非您希望有很多长度为 -4 的数组。该标准将无符号类型 size_t 指定为足够大以存储对象大小和数组索引的无符号类型。使用任何其他类型都不能保证有效。

The real answer (in my humble but ever-so-correct opinion :P) is not to use scanf. Use fgets to read the first line (i.e. the number) and then parse that string yourself with, say, sscanf or strtoul. That way you have the ability to handle errors when someone doesn't input the data in a nice format, and you don't have to hack around scanf's lack of robust whitespace handling.

Also, never used an int to store sizes unless you expect to have a lot of arrays with -4 length. The standard specifies the unsigned type size_t as an unsigned type that is large enough to store object sizes and array indices. Using any other type isn't guaranteed to work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文