【问题标题】:K&R 2nd Edition, Example 1.9 Character ArraysK&R 第 2 版,示例 1.9 字符数组
【发布时间】:2013-10-12 19:58:32
【问题描述】:

我对以下代码中的 getline() 函数和参数定义有疑问。代码直接取自 K&R 第 1.9 章:“字符数组”。我在这里逐字转载。问题是,当我按原样编译程序时,我得到三个错误,(我在最后复制了)。当我在出现错误的三个地方将函数和函数参数定义更改为 get_line()(使用下划线而不是仅 getline)时,错误停止并且程序按预期运行。

我的问题是:

C 中发生了什么变化,使得 getline() 无效,但 get_line() 是函数定义的有效名称?

#include <stdio.h>
#define MAXLINE 1000    // maximum input line size

int getline(char line[], int maxline);
void copy(char to[], char from[]);

/* print longest input line */

int main()
{
    int len;            //current line lenght
    int max;            //maximum length seen so far
    char line[MAXLINE]; //current input line
    char longest[MAXLINE];//longest line saved here

    max = 0;
    while ((len = getline(line, MAXLINE)) > 0)
        if (len > max) {
            max = len;
            copy(longest, line);
        }
        if (max > 0)   //there was a line
            printf("%s", longest);
            return 0;
}

/*  getline: read a line into s, return length */
int getline(char s[], int lim)
{
    int c, i;

    for (i = 0; i<lim-1 && (c=getchar()) != EOF && c !='\n'; ++i) 
        s[i] = c;
    if (c == '\n') {
        s[i] = c;
        ++i;
    }
        s[i] = '\0';
        return i;
}


/* copy: copy 'from' into 'to'; assume to is big enough */
void copy(char to[],char from[])
{
    int i;

    i = 0;
    while ((to[i] = from[i]) != '\0') {
        ++i;
    }
}

我得到的错误是:

  • ./section 1.9.1.c:4:5: 错误:'getline' 的类型冲突; int getline(int line[], int maxline);

  • ./section 1.9.1.c:17:40: 错误:函数调用的参数太少,预期 3,有 2 while ((len = getline(line, MAXLINE)) &gt; 0);

  • ./section 1.9.1.c:30:5:错误:“getline”的类型冲突 int getline(int s[], int lim)

【问题讨论】:

  • 这不是答案,只是对 K&R 的一般评论:不要使用那本书中提倡的做法。
  • 现在不能聊天;只需简要说明 2 美分,为什么您不应该从 K&R 开始,原因有两个。 1:K&R 倡导 30 年前流行的做法,在人们开始明白这种做法经常导致代码错误并且总是导致代码可维护性差之前,这种做法很流行。最近有很多关于C的书。 2:如果你的目标是objective-C,那么你应该从一本objective-C的书开始:即使C的特性是retain,思考如何编程的方式也可能有很大的不同语言之间,你不应该用另一种污染。

标签: c arrays kernighan-and-ritchie


【解决方案1】:

glibc 一起分发的stdio 库声明了一个也称为getline 的函数,其签名与您的签名不同。由于您不能声明两个具有相同名称的函数,因此编译器会报错。在 stdio.h 中发现的 getline 的冲突声明是:

   ssize_t getline(char **lineptr, size_t *n, FILE *stream);

getline 函数最初是一个 glibc 扩展,后来被包含在 POSIX.1-2008 中。 它不是标准的 C 函数。

如果您使用gcc,您可以使用-std 命令行开关获得符合标准的行为。除其他外,这隐藏了非标准函数的声明。举个例子:

gcc -Wall -pedantic -std=c11 "section 1.9.1.c" -o "section 1.9.1"

【讨论】:

  • 好的,谢谢。我想知道除了我得到的错误之外还有什么笔记:/usr/include/stdio.h:449:9: note: previous declaration is here ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAI...
  • 取决于“标准”的含义,getline 是在“a”标准中定义的,而不是在任何官方 C 语言标准中......关键是,如果你想使用gcc 编写标准C,您可以使用-std 命令行开关。
  • 符合标准的 gcc 建议不起作用,我仍然遇到相同的错误。但是我现在完全理解这里发生了什么:/usr/include/stdio.h:449:9: note: previous declaration is here ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAI... 再次感谢,非常有帮助。
  • 使用-std=c11(或-std=c99,或-ansi)肯定会起作用。
  • 先生,我是否应该阅读K&R第二版,我在这方面感到困惑,因为语言有变化,我想就这件事得到建议,你能帮忙吗?
【解决方案2】:

stdio.h已经有getline()的声明,

您不应使用相同的名称来定义您的 getline 函数。

如果你想声明和定义相同的函数,你应该使用另一个名字。喜欢get_line()

【讨论】:

  • 我就是这么想的。谢谢。
【解决方案3】:

新声明的 getline 函数与 stdio.h 中声明的函数之间存在冲突。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-04
    相关资源
    最近更新 更多