为什么gets()假设extern在C中的代码中返回int?

时间:2015-12-29 19:59:39

标签: c gets

#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的错误,我只是试图扫描一个字符串。

3 个答案:

答案 0 :(得分:8)

最可能的原因是gets() function has been deprecated有一段时间了。它看起来已从您系统上的<stdio.h>中删除。

幸运的是,这种情况很容易解决:用fgets()替换呼叫,如下所示:

fgets(buffer, sizeof(buffer), stdin);

注意: fgets gets的替代品,因为它会在最后保留'\n'个字符它返回的字符串中的行。这个Q&A讨论了这个问题,并提供了解决方案。

答案 1 :(得分:2)

已从C标准中删除gets()功能。它从来都不是一个好的函数,因为没有办法告诉gets参数缓冲区有多大,如果输入文件来自不受信任的来源,很容易导致缓冲区溢出甚至恶意攻击。您的编译器抱怨假设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")] = '\0'; // 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;
}

答案 2 :(得分:0)

gets()在C99中已弃用,并从标准C中删除了C11。

OP收到警告“关于假设extern返回int”,因为它不是标准包含文件中的原型。

使用gets() @dasblinkenlight

大致可以用其他内容替换fgets()

使用新代码,请使用fgets()及其怪癖。

要推广您自己的my_gets(char *dest, size_t size),具有高度的gets()兼容性,代码应该:

  1. 获取与目标数组大小匹配的大小参数。

  2. 在为目标数组读取太多字符时,my_gets()可以自由执行任何合理的功能,因为此前gets()会导致未定义的行为。建议尽可能地填充数组,消耗字符直至'\n'EOF,并返回NULL以指示错误(可能的设置errno)。

  3. 简单使用fgets()是有问题的,因为传递给fgets()的大小是字符的空间,'\n''\0',而传递的大小到my_gets()真的应该是角色和'\0'所需的空间。 '\n'被消费而未保存。

  4. 使用VLA满足这些目标的候选函数位于https://stackoverflow.com/a/34031881/2410359