Problem with scanf and fgets

我与影子孤独终老i 提交于 2019-12-30 07:20:28

问题


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.


回答1:


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.




回答2:


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



来源:https://stackoverflow.com/questions/4929338/problem-with-scanf-and-fgets

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!