【发布时间】:2018-08-04 08:44:20
【问题描述】:
标准库函数fgets()有两个缺点:
- 函数的第二个参数类型为
int - 它在提供的缓冲区中留下一个尾随换行符
我做了一个类似于fgets() 的简单函数,排除了上述缺点,以尝试提高我的一个程序的效率,该程序获取文本文件的行并在新的位置终止char 数组-line 字符使用函数strcspn()。
但它真的更有效吗?为什么标准库函数比以下幼稚的实现具有优势?
#include <stdio.h>
char *my_fgets(char *buf, size_t maxCount, FILE *stream);
int main(int argc, char **argv)
{
if (argc < 2)
{
fprintf(stderr, "Usage: %s [filename]", argv[0]);
}
FILE *fp;
fp = fopen(argv[1], "r");
if (!fp)
{
perror(argv[1]);
return 1;
}
char buf[256];
/*while (fgets(buf, sizeof(buf), fp))
{
buf[strcspn(buf, "\n")] = '\0';
// . . .
puts(buf);
}*/
while (my_fgets(buf, sizeof(buf) - 1, fp))
{
puts(buf);
}
return 0;
}
char *my_fgets(char *buf,
size_t maxCount, FILE *stream)
{
int ch;
size_t n = 0;
while ((ch = fgetc(stream)) != EOF)
{
if (ch == '\n' || n == maxCount)
{
break;
}
else
{
buf[n++] = ch;
}
}
if (n == 0 && ch == EOF)
{
return NULL;
}
buf[n] = '\0';
return buf;
}
【问题讨论】:
-
这个问题似乎更适合Code Review
-
我认为您的问题would be on topic there:“以下领域的开放式反馈:最佳实践和设计模式使用、安全问题、性能、意外情况下的正确性”
-
它可能效率较低的一个原因是标准库版本可能使用较低级别的操作系统特定 I/O 函数,而不是使用
fgetc(),并且可以使用手工制作的汇编程序来实现针对目标系统的性能进行了调整。该标准仅指定了fgets()的净效果——它不要求使用fgetc()实现fgets(),甚至不需要用C 编写。 -
您的函数很容易出错:它将
maxCount + 1字节写入缓冲区,这与fgets不同。如果达到maxCount限制,它会丢弃字符:如果流包含hello并且您调用my_fgets(buf, 1, fp),它会将"h"存储在buf中并丢弃'e',将llo留在流中。并且无法区分完整的行(到达实际的行尾 (\n))和部分行(my_fgets停止,因为读取了maxCount字符)。 -
@machine_1 - 是的,您要么有一个尾随
'\n',要么您已读取指定的最大字符数,但缓冲区末尾没有'\n'。
标签: c performance function fgets standard-library