如何实现 'malloc' 和 'fgets' 来读取和打印输入流

How do I implement 'malloc', and 'fgets' to read and print the input stream

我有一个挑战:要求用户先输入最大字符数,然后再输入字符串。应该动态分配内存,打印输入的字符串。

我的代码;

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main()
    {
        int size;
        char * pText = NULL;
        
        // get the maximum string length
        printf("\nEnter maximum length of string (a number): ");
        scanf("%d", &size);
        
        // allocate memory
        pText = (char *)malloc(size * sizeof(char));
    
        if(pText != NULL)
        {
            // get user's input string
            printf("\nEnter your string:\n");
            fgets(pText, size, stdin);
    
            printf("\nThe input string is %s.\n", pText);
        
        }
    
        free(pText);
    
        return 0;
    }

这是所有的代码。我遇到的问题是在 if 块中;最初实现的代码是,

    scanf(" ");
    gets(pText);

    printf("\nThe inputted string is %s.\n", *pText);

我认为这是一种魔法,它可以从 scanf 中删除终止字符,从而使 gets 能够读取带有终止字符的字符串(如果我的信息正确的话);它尚未得到充分解释。虽然该实现有效,但有人告诉我可以使用 fgets 来实现相同的功能。

我尝试实现 fgets 导致用户无法输入字符串的结果,因为程序在输入最大字符数(作为整数)后终止并且 <return> 已经被压。我相信因为 pText 为 NULL 或零,所以程序在可以写入任何文本之前终止。

我曾尝试阅读 fgets 的主题,但大多数示例涉及从输入文件而不是 stdin 接受数据。我不确定问题出在哪里,或者我哪里出错了,但我希望得到一些启发。

您的问题是您在同一个程序中混用了 scanffgets。这是可能的,但仅限于谨慎的程序员,因为 scanf 一旦完成转换或发现错误就会停止读取。

因此,当您的用户键入 10Return 时,scanf 会读取1 和 0 字符(形成 10) 并在输入缓冲区 中留下一个 '\n' 字符。在下一个 fgets 上,您立即得到一个空行并正常退出程序,表示未读取任何内容。

您至少应该清理输入缓冲区直到行尾:

scanf("%d", &size);
while (((int c = fgetc(stdin)) != '\n') && (c != EOF));  // read up to the end of line

这应该足以解决读取问题,但您应该考虑控制 return 值或 scanf 以及大小的有效性(xyz-1作为输入?)。

那么如果你想fgets正确地return一行最多size个有用的字符,你应该给它一个size + 2个字符的缓冲区,用一个地方对于换行符和终止空值(顺便说一句 sizeof(char) 每个标准是 1)。

// allocate memory
pText = (char *)malloc(size + 2);     // do not forget the new line and the null

最后,你可以用 strcspn

去掉换行符
    fgets(pText, size, stdin);
    pText[strcspn(pText, "\r\n")] = '[=12=]';  // remove the optional end of line