为什么 gets() 假设 extern 在 C 代码中返回 int?
Why does gets() assuming extern returning int in this code in C?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
int length;
char **lines, buffer[80];
printf("How many lines do you want to enter?.\n");
scanf("%d", &length);
getchar();
lines = (char**)malloc(length * sizeof(char*));
for (i = 0; i < length; ++i) { //Scan user's lines
gets(buffer);
lines[i] = (char*)malloc(strlen(buffer) * sizeof(char) + 1);
if (!lines[i]) { //Check if allocation available
printf("Error! Out of memory!");
return endProgram;
}
strcpy(lines[i], buffer);
}
return 0;
}
我想知道为什么 gets()
函数会给我一个假设 extern 返回 int 的错误,我只是想扫描一个字符串。
最有可能的原因是 gets()
function has been deprecated 有一段时间了。它似乎已从您系统上的 <stdio.h>
中删除。
幸运的是,这种情况很容易解决:将调用替换为 fgets()
,如下所示:
fgets(buffer, sizeof(buffer), stdin);
注意: fgets
不是 drop-in gets
的替代品,因为它在 returns 所在的字符串的行尾保留 '\n'
个字符。 Q&A 讨论了这个问题,并提供了解决方案。
gets()
函数已从 C 标准中删除。它从来都不是一个好用的函数,因为无法告诉 gets
参数缓冲区有多大,如果输入文件来自不受信任的来源,很容易导致缓冲区溢出甚至恶意攻击。您的编译器抱怨 assuming extern 返回 int 的原因是 gets
的原型不再出现在您的 <stdio.h>
系统头文件中。
这样修改你的代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
int length;
char **lines, buffer[81];
printf("How many lines do you want to enter?.\n");
if (scanf("%d", &length) != 1)
return 1;
getchar(); // consuming the line feed typed by the user.
lines = malloc(length * sizeof(char*));
if (lines == NULL) {
printf("Error! Out of memory!\n");
return 2;
}
for (i = 0; i < length; i++) { //Scan user's lines
if (!fgets(buffer, sizeof buffer, stdin)) {
printf("Error! Premature end of file!\n");
return 2;
}
buffer[strcspn(buffer, "\n")] = '[=10=]'; // overwrite the final \n
lines[i] = strdup(buffer);
if (lines[i] == NULL) {
printf("Error! Out of memory!\n");
return 2;
}
}
// perform other work on the buffer.
return 0;
}
gets()
在 C99 中被弃用,并从 C11 的标准 C 中删除。
OP 收到警告 "about assuming extern returning int" 因为它不是标准包含文件中的原型。
要用其他东西替换 gets()
大约可以用 fgets()
使用新代码,使用 fgets()
及其怪癖。
要滚动自己的 my_gets(char *dest, size_t size)
,与前 gets()
高度兼容,代码应该:
取一个与目标数组大小匹配的大小参数。
在为目标数组读取太多字符后,my_gets()
可以自由执行任何合理的功能,因为前者 gets()
此时会导致未定义的行为。建议尽可能填充数组,消耗字符直到'\n'
或EOF
,并返回NULL
表示错误(可能设置errno
)。
fgets()
的简单使用是有问题的,因为传递给 fgets()
的大小是字符的 space,'\n'
和 '[= 25=]'
,而传递给 my_gets()
的大小实际上应该是字符和 '[=25=]'
所需的 space。 '\n'
正在消耗且未保存。
使用 VLA 满足这些目标的候选函数位于 。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
int length;
char **lines, buffer[80];
printf("How many lines do you want to enter?.\n");
scanf("%d", &length);
getchar();
lines = (char**)malloc(length * sizeof(char*));
for (i = 0; i < length; ++i) { //Scan user's lines
gets(buffer);
lines[i] = (char*)malloc(strlen(buffer) * sizeof(char) + 1);
if (!lines[i]) { //Check if allocation available
printf("Error! Out of memory!");
return endProgram;
}
strcpy(lines[i], buffer);
}
return 0;
}
我想知道为什么 gets()
函数会给我一个假设 extern 返回 int 的错误,我只是想扫描一个字符串。
最有可能的原因是 gets()
function has been deprecated 有一段时间了。它似乎已从您系统上的 <stdio.h>
中删除。
幸运的是,这种情况很容易解决:将调用替换为 fgets()
,如下所示:
fgets(buffer, sizeof(buffer), stdin);
注意: fgets
不是 drop-in gets
的替代品,因为它在 returns 所在的字符串的行尾保留 '\n'
个字符。 Q&A 讨论了这个问题,并提供了解决方案。
gets()
函数已从 C 标准中删除。它从来都不是一个好用的函数,因为无法告诉 gets
参数缓冲区有多大,如果输入文件来自不受信任的来源,很容易导致缓冲区溢出甚至恶意攻击。您的编译器抱怨 assuming extern 返回 int 的原因是 gets
的原型不再出现在您的 <stdio.h>
系统头文件中。
这样修改你的代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
int length;
char **lines, buffer[81];
printf("How many lines do you want to enter?.\n");
if (scanf("%d", &length) != 1)
return 1;
getchar(); // consuming the line feed typed by the user.
lines = malloc(length * sizeof(char*));
if (lines == NULL) {
printf("Error! Out of memory!\n");
return 2;
}
for (i = 0; i < length; i++) { //Scan user's lines
if (!fgets(buffer, sizeof buffer, stdin)) {
printf("Error! Premature end of file!\n");
return 2;
}
buffer[strcspn(buffer, "\n")] = '[=10=]'; // overwrite the final \n
lines[i] = strdup(buffer);
if (lines[i] == NULL) {
printf("Error! Out of memory!\n");
return 2;
}
}
// perform other work on the buffer.
return 0;
}
gets()
在 C99 中被弃用,并从 C11 的标准 C 中删除。
OP 收到警告 "about assuming extern returning int" 因为它不是标准包含文件中的原型。
要用其他东西替换 gets()
大约可以用 fgets()
使用新代码,使用 fgets()
及其怪癖。
要滚动自己的 my_gets(char *dest, size_t size)
,与前 gets()
高度兼容,代码应该:
取一个与目标数组大小匹配的大小参数。
在为目标数组读取太多字符后,
my_gets()
可以自由执行任何合理的功能,因为前者gets()
此时会导致未定义的行为。建议尽可能填充数组,消耗字符直到'\n'
或EOF
,并返回NULL
表示错误(可能设置errno
)。fgets()
的简单使用是有问题的,因为传递给fgets()
的大小是字符的 space,'\n'
和'[= 25=]'
,而传递给my_gets()
的大小实际上应该是字符和'[=25=]'
所需的 space。'\n'
正在消耗且未保存。
使用 VLA 满足这些目标的候选函数位于 。