如何在stdio.h中实现getline函数的自定义版本(CLANG,OS X)(答案:更改用于编译的POSIX标准)

ptd*_*ker 5 c posix stdio clang getline

晚上好,

我正在研究Kernighan和Ritchie的经典"C编程语言"中的练习.

在几个地方,练习可以创建自己的函数版本,该函数复制标准库中函数的名称.而不是为我的版本创建一个替代名称,我真的想告诉编译器我宁愿使用我的函数版本,然后使用标准库函数.

具体来说,如果我尝试编译一个解决方案来练习1-18,它从每行输入中删除尾随空格和制表符,我使用函数'getline'来读取stdin中的行.不幸的是,这会产生编译器错误,因为getline是在stdio.h中定义的.

我曾尝试使用#undef,但似乎无法使用它.

我已经搜索过其他类似的问题并找到了[这一个] [1]; 然而,它似乎需要黑客标准的库标题,我宁愿不这样做.

提前谢谢你的帮助.

这是代码(为了简短而删除了我的评论):

#include <stdio.h>
#include <stdlib.h>

#define MAXLINE 1000

static size_t getline(char s[], size_t lim) {

    char   c;
    size_t i = 0;

    while (--lim > 0 && (c = (char)getchar()) != (char)EOF && c != '\n')
        s[i++] = c;
    if (c == '\n')
        s[i++] = c;
    s[i] = '\0';

    return i;
}

int main(void) {

    char   line[MAXLINE] = "";
    size_t len = 0;

    while ((len = getline(line, MAXLINE)) > 0)
        if (len > MAXLINE)
            printf("%s", line);

    exit(EXIT_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)

而且,我得到的错误是:

cc -std=c99 -Wall -g -I. -c -o obj/cleantrailsnblanks.o cleantrailsnblanks.c
cleantrailsnblanks.c:14:15: error: static declaration of 'getline' follows non-static declaration
static size_t getline(char s[], size_t lim) {
              ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/stdio.h:442:9: note: previous declaration is here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
        ^
cleantrailsnblanks.c:35:40: error: too few arguments to function call, expected 3, have 2
    while ((len = getline(line, MAXLINE)) > 0)
                  ~~~~~~~              ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/stdio.h:442:1: note: 'getline' declared here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
^
2 errors generated.
make: *** [obj/cleantrailsnblanks.o] Error 1
Run Code Online (Sandbox Code Playgroud)

更新1

从我的定义中删除'static'后,错误变为:

cc -std=c99 -Wall -g -I. -c -o obj/cleantrailsnblanks.o cleantrailsnblanks.c
cleantrailsnblanks.c:14:8: error: conflicting types for 'getline'
size_t getline(char s[], size_t lim) {
       ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/stdio.h:442:9: note: previous declaration is here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
        ^
cleantrailsnblanks.c:35:40: error: too few arguments to function call, expected 3, have 2
while ((len = getline(line, MAXLINE)) > 0)
              ~~~~~~~              ^
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/stdio.h:442:1: note: 'getline' declared here
ssize_t getline(char ** __restrict, size_t * __restrict, FILE * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
^
2 errors generated.
make: *** [obj/cleantrailsnblanks.o] Error 1
Run Code Online (Sandbox Code Playgroud)

回答

请参阅此讨论: 为什么在编译K&R2第1章中的最长行示例时,会出现"getline的冲突类型"错误?

解决方案是在包含stdio.h之前添加这两行:

#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
Run Code Online (Sandbox Code Playgroud)

这将设置编译使用的代码的标准POSIX.1-2001,而不是在其中GNU函数getline()扩展被添加到标准的POSIX.1-2008标准.

ptd*_*ker 2

请参考这两个讨论(第二个最相关):

解决方案是在包含 stdio.h 之前添加这两行:

#undef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
Run Code Online (Sandbox Code Playgroud)

这设置使用 POSIX.1-2001 标准来编译代码,而不是使用 POSIX.1-2008 标准(其中将 GNU getline() 扩展添加到标准中)。