是否有GNU getline接口的替代实现?

我目前正在进行的实验使用的软件库具有复杂的源历史记录,并且没有明确定义的许可证。 合理化事物并在固定许可下发布将是一项相当大的工作。

它也打算运行一个随机的unixish平台,只有我们支持的一些libc有GNU getline,但现在代码期望它。

有没有人知道在限制较少的许可下可以重新实现GNU getline语义?

编辑::我问,因为谷歌没有帮助,我想尽可能避免写一个(这可能是一个有趣的练习,但它不能最好地利用我的时间。)

更具体地说,有问题的界面是:

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

看看Paul Hsieh关于用户输入的页面。 如果您想了解确切的条款,可以通过电子邮件发送给作者。

我很困惑。

我查看了链接,阅读说明,这是一个很好的实用程序。

但是,你是说你根本无法将此function重写为规范吗? 规范似乎很清楚,

这里:

 /* This code is public domain -- Will Hartung 4/9/09 */ #include  #include  size_t getline(char **lineptr, size_t *n, FILE *stream) { char *bufptr = NULL; char *p = bufptr; size_t size; int c; if (lineptr == NULL) { return -1; } if (stream == NULL) { return -1; } if (n == NULL) { return -1; } bufptr = *lineptr; size = *n; c = fgetc(stream); if (c == EOF) { return -1; } if (bufptr == NULL) { bufptr = malloc(128); if (bufptr == NULL) { return -1; } size = 128; } p = bufptr; while(c != EOF) { if ((p - bufptr) > (size - 1)) { size = size + 128; bufptr = realloc(bufptr, size); if (bufptr == NULL) { return -1; } } *p++ = c; if (c == '\n') { break; } c = fgetc(stream); } *p++ = '\0'; *lineptr = bufptr; *n = size; return p - bufptr - 1; } int main(int argc, char** args) { char *buf = NULL; /*malloc(10);*/ int bufSize = 0; /*10;*/ printf("%d\n", bufSize); int charsRead = getline(&buf, &bufSize, stdin); printf("'%s'", buf); printf("%d\n", bufSize); return 0; } 

15分钟,我在10年内没有写过C. 它稍微破坏了getline契约,因为它只检查lineptr是否为NULL,而不是NULL和n == 0.如果你愿意,可以修复它。 (另一个案例对我来说没有多大意义,我想你可以在这种情况下返回-1。)

将’\ n’替换为变量以实现“getdelim”。

人们还在写代码吗?

Will Hartung的代码遇到了一个非常严重的问题。 realloc很可能会释放旧块并分配一个新块,但代码中的p指针将继续指向原始块。 这个尝试通过使用数组索引来解决这个问题。 它还试图更紧密地复制标准POSIX逻辑。

 /* The original code is public domain -- Will Hartung 4/9/09 */ /* Modifications, public domain as well, by Antti Haapala, 11/10/17 */ #include  #include  #include  #include  // if typedef doesn't exist (msvc, blah) typedef intptr_t ssize_t; ssize_t getline(char **lineptr, size_t *n, FILE *stream) { size_t pos; int c; if (lineptr == NULL || stream == NULL || n == NULL) { errno = EINVAL; return -1; } c = fgetc(stream); if (c == EOF) { return -1; } if (*lineptr == NULL) { *lineptr = malloc(128); if (*lineptr == NULL) { return -1; } *n = 128; } pos = 0; while(c != EOF) { if (pos + 1 >= *n) { size_t new_size = *n + (*n >> 2); if (new_size < 128) { new_size = 128; } char *new_ptr = realloc(*lineptr, new_size); if (new_ptr == NULL) { return -1; } *n = new_size; *lineptr = new_ptr; } ((unsigned char *)(*lineptr))[pos ++] = c; if (c == '\n') { break; } c = fgetc(stream); } (*lineptr)[pos] = '\0'; return pos; } 

如果您正在为BSD编译,请使用fgetln

使用NetBSD中的这些可移植版本: getdelim()getline()

它们来自pkgsrc中的libnbcompat,并且在每个文件的顶部都有一个BSD许可证。 你需要两个,因为getline()调用getdelim()。 获取这两个文件的最新版本。 请参阅每个文件顶部的BSD许可证。 修改文件以适合您的程序:您可能需要在其中一个头文件中声明getline()和getdelim(),并修改这两个文件以包含头而不是nbcompat头。

此版本的getdelim()是可移植的,因为它调用fgetc()。 相比之下,来自libc(如BSD libc或musl libc)的getdelim()可能会使用该libc的私有function,因此它不适用于跨平台。

自POSIX 2008指定getline()以来,更多的Unixish平台添加了getline()函数。 缺少getline()是罕见的,但它仍然可以在旧平台上发生。 有些人尝试在旧平台(如PowerPC Mac OS X)上引导NetBSD pkgsrc,因此他们希望libnbcompat提供缺少的POSIX函数,如getline()。