我想阅读用户的输入并保存。我现在有什么工作,但我需要知道它是否合法(遵循ansi标准 - c90)scanf在为输入分配内存之前首先分配变量“length”,或者它只是编译器的一个怪癖。
#include <stdio.h>
int main()
{
char* text;
int length = 0;
scanf("%s%n", text = malloc(length+1), &length);
printf("%s", text);
return 0;
}
这不会像你期望的那样工作。
在你调用malloc
的时候,length
的值仍为0,所以你只需要分配一个字节。 length
直到scanf
返回后才更新。因此,任何非空字符串都将写入已分配缓冲区的边界,并调用undefined behavior。
虽然不完全相同,但你可以做的是使用getline
,假设你在一个POSIX系统上运行,比如Linux。此函数读取一行文本(包括换行符)并为该行分配空间。
char *text = NULL;
size_t n = 0;
ssite_t rval = getline(&text, &n, stdin);
if (rval == -1) {
perror("getline failed");
} else {
printf("%s", text);
}
free(text);
除了在另一个答案中解决了scanf
滥用的明显问题之外,这不符合任何C标准:
#include <stdio.h>
...
text = malloc(length+1)
由于你没有找到stdlib.h
,其中malloc
被发现,C90将假设函数malloc
具有int malloc(int);
形式,这当然是无稽之谈。
然后当你尝试将int
(malloc的结果)分配给char*
时,你有一个约束违反C90 6.3.16.1,简单赋值的规则。
因此,不允许您的代码干净地编译,但编译器必须提供诊断消息。
您可以通过升级到标准ISO C来避免此错误。
其他人解释的问题很好
我想阅读用户的输入并保存
要添加并满足OP的目标,类似的代码可以做到
int length = 255;
char* text = malloc(length+1);
if (text == NULL) {
Handle_OOM();
}
scanf("%255s%n", text, &length);
// Reallocate if length < 255 and/or
if (length < 255) {
char *t = realloc(text, length + 1);
if (t) text = t;
} else {
tbd(); // fail when length == 255 as all the "word" is not certainly read.
}
如果过度投入被认为是敌对的,那么上述将是一种简单的方法。