如何实现 '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
接受数据。我不确定问题出在哪里,或者我哪里出错了,但我希望得到一些启发。
您的问题是您在同一个程序中混用了 scanf
和 fgets
。这是可能的,但仅限于谨慎的程序员,因为 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
我有一个挑战:要求用户先输入最大字符数,然后再输入字符串。应该动态分配内存,打印输入的字符串。
我的代码;
#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
接受数据。我不确定问题出在哪里,或者我哪里出错了,但我希望得到一些启发。
您的问题是您在同一个程序中混用了 scanf
和 fgets
。这是可能的,但仅限于谨慎的程序员,因为 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