我正在练习我的C编码,为了学习目的,我想在C中实现我自己版本的getline函数。我想回顾一下代码的风格、正确性、对性能的改进以及代码的总体质量。我主要关心的是正确性和性能(按顺序排列)。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_LINE_LENGTH 255
/* Retrieves a line of text from the stream provided
* and places it into @buf until a new line character is
* reached or the number of characters read is > @size - 1.
* This function will null-terminate the provided buffer.
*
* @param[in] -- stream -- the stream
* @param[in] -- buf -- a buffer big enough for @size chars.
* @param[in] -- size -- the maximum number of chars to read (must
* include room for a null terminator
* @return -- the number of characters read from the stream.
*/
size_t getline(FILE *stream, char *buf, size_t size)
{
size_t count = 0;
char c;
while ((c = (char)getc(stream)) != '\n' && count < size - 1) {
buf[count++] = c;
}
buf[count] = '\0';
return count;
}
int main()
{
char line[MAX_LINE_LENGTH];
while (true) {
size_t count = getline(stdin, line, MAX_LINE_LENGTH);
printf("The line gotten was \"%s\" and was %zu chars long.\n", line, count);
}
}发布于 2016-02-07 22:27:51
getline函数看起来更像是fgets的变体,而不是getline。size == 0,size - 1 == SIZE_MAX,一个很大的数字。getline从流读取到size字节,尽管它只将size - 1放置到缓冲区中。它只是悄悄地删除了最后一个字节。您应该切换循环条件的顺序: while (count < size & (c = (char)getc(stream)) != '\n') {.}getline写入终止空字节时,如果size为0时,它也会将其参数定义的范围外的内存写入内存中。getc(stream) == EOF是一个错误条件,您的getline函数将继续尝试从流中读取,始终“读取”EOF,将(char) EOF (通常是'\xff')放置到缓冲区中,直到到达缓冲区的末尾。您可以通过将stdin指向一个空文件来尝试此操作。for循环而不是while循环。它会更清楚,什么是增加,地点和方式。考虑到以上几点,我将重写您的函数:
ssize_t fgets(FILE *stream, char *buf, size_t size)
{
if (size == 0)
return 0;
size_t count;
int c = 0;
for (count = 0; c != '\n' && count < size - 1; count++)
{
c = getc(stream);
if (c == EOF) {
if (count == 0)
return -1;
break;
}
buf[count] = (char) c;
}
buf[count] = '\0';
return (ssize_t) count;
}https://codereview.stackexchange.com/questions/119219
复制相似问题