简体   繁体   English

为什么在使用malloc()动态分配内存后,字符数组打印出的字符数比需要少一个?

[英]Why is array of chars printing one less char than needed after dynamically allocating memory with malloc()?

The problem I am facing is that if I enter in 5 characters into an array using a loop that scanf's each character separately it only prints out 4 of the characters in the array (using a loop again). 我面临的问题是,如果我使用scanf的每个字符分开的循环向数组中输入5个字符,那么它只会打印出数组中的4个字符(再次使用循环)。 This problem does not arise if I do not dynamically allocate memory to the array. 如果我不动态分配内存到数组,则不会出现此问题。

 int main() {

    int nchars = 0;
    char* arr = NULL; 


    printf("Enter number of characters you want in string: "); scanf("%d", &nchars);

    arr = (char*)malloc(nchars * sizeof(char));

    printf("Enter characters you want in the array: \n");
    for (int i = 0; i < nchars; ++i) {
        scanf("%c\n", &arr[i]);
    }

    for (int i = 0; i < nchars; ++i) {
        printf("%c", arr[i]);
    }

    free(arr);
    return 0;
}

Terminal: 终奌站:

Enter number of characters you want in string: 5
Enter characters you want in the array:
a
m
i
i
i

amii (output)

If I do not put a \\n after the %c in the scan statement it only scans two chars and outputs them on new lines like this: 如果我没有在扫描语句中的%c后面加上\\ n,它将仅扫描两个字符并将它们输出到新行,如下所示:

Enter number of characters you want in string: 5
Enter characters you want in the array:
a
m

a
m

I have tried different variations where I would create a temp array and strcpy() to the dynamically allocated char arr but still nothing. 我尝试了各种变体,其中我将创建一个temp数组和strcpy()到动态分配的char arr,但仍然没有。 As well as: 以及:

arr = (char*)malloc((nchars + 1) * sizeof(char));

To see if allocating one more byte would add the last letter. 要查看是否再分配一个字节会增加最后一个字母。

The problem is that scanf("%d", ...) leaves the newline character in the input stream. 问题是scanf("%d", ...)将换行符留在输入流中。 When you get to the scanf("%c\\n", ...) it reads the newline and the character you typed stays in the input stream, meaning you're off by one. 当您到达scanf("%c\\n", ...)它会读取换行符,并且您键入的字符将保留在输入流中,这意味着您的位置差了一个。 You'll notice that in your output there's a blank line before amii is printed. 您会注意到在输出中,在打印amii之前有一个空白行。

The solution is to have scanf skip whitespace. 解决的办法是让scanf跳过空白。 Change your loop to this: 将您的循环更改为此:

for (int i = 0; i < nchars; ++i) {
    scanf(" %c", &arr[i]);
}

Putting a space before the %c means skip leading whitespace . %c之前放置一个空格表示跳过前导空白

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM