使用 getline 与 fgets 进行基本文件打印
Using getline vs fgets for basic file printing
我正在使用以下命令打印文件的行:
int main() {
FILE *fptr = fopen("test20k.csv", "r");
char buffer[MAXLINE];
while (fgets(buffer, sizeof(buffer), fptr) != NULL)
printf("%s", buffer);
putchar('\n');
return 0;
}
如何使用 getline
完成同样的事情?这是一个更概念化的类似问题:.
您只需检查 getline(3) - Linux manual page 以确定要传递的适当参数类型和要处理的 return 类型以及 getline
如何指示 success/failure。
然后只需将代码中的 fgets()
替换为 getline()
即可。所有 line-oriented 输入函数读取并包含尾随 '\n'
,因此那里没有变化。但是,请注意 getline()
为您的 buffer
分配存储空间,因此您需要 free()
完成后 buffer
-- 要求您包含 [=21] =] 除了 stdio.h
.
此外,您注意到 getline
不是标准 C 库的一部分。相反,getline
是一个 POSIX 函数,因此并非每个 C 实现都需要提供它,因此您可能会遇到可移植性问题。
基本上就是这样。但是,在您的代码中,您不应使用 硬编码文件名 。这就是 main()
接受参数的原因之一。因此,只需将要读取的文件名作为第一个参数传递给您的程序(如果没有提供参数,您也可以默认从 stdin
读取)
将它们放在一起,作为最低限度的实现,您可以这样做:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv) {
size_t n = 0; /* initial alloc size, 0 - getline decides */
char *buffer = NULL; /* pointer to block of mem holding input */
/* use filename provided as 1st argument (stdin by default) */
FILE *fptr = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fptr) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
/* you pass the address of your buffer and a pointer to n */
while (getline (&buffer, &n, fptr) != -1)
printf("%s", buffer);
putchar('\n');
if (fptr != stdin) /* close file if not stdin */
fclose (fptr);
free (buffer); /* getline allocates, don't forget to free */
return 0;
}
检查一下,如果您还有其他问题,请告诉我。
示例输入文件
$ cat dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
例子Use/Output
$ ./bin/getline_file dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
fgets()/getline()
常用于阅读文本.
不常见的是,输入流包含 空字符 '[=13=]'
.
fgets()
像任何字符一样读取 空字符 。它不会停止读取输入的 行。
以下仅打印到 字符串 中遇到的第一个 空字符 - 它与读取 [=37= 没有区别]空字符和fgets()
添加的附加空字符。
while (fgets(buffer, sizeof(buffer), fptr)) {
printf("%s", buffer); // Maybe stops too early?
}
getline()
,虽然不是标准的 C,但有一个优势,因为它 returns 读取的字符数。然后打印可以打印到返回的计数,而不是仅打印到第一个 空字符 .
size_t n = 0;
char *buffer = NULL;
ssize_t sz;
while ((sz = getline (&buffer, &n, fptr)) != -1) {
fwrite(buffer, 1, sz, stdout);
}
free(buffer);
注:size_t n = 0; char *buffer = NULL;
为初始设置。 getline (&buffer, &n, ...)
接收这两个变量的地址,允许它根据需要更新这两个变量(由于重新分配)。最大缓冲区大小为 SIZE_MAX
或内存池的限制。我们不需要知道它在 getline()
中是如何工作的,因为这是一个不同的实现细节。
虽然 空字符 在简单的文本文件中并不常见,但我发现编写最适合 be prepared for for null characters. They readily come up is reading a text file that is UTF16 encoded. Of course expecting an ASCII or UTF8 文本文件的代码并获得 UTF16 是一个问题,很好地打印想法 空字符 有助于识别问题。
我正在使用以下命令打印文件的行:
int main() {
FILE *fptr = fopen("test20k.csv", "r");
char buffer[MAXLINE];
while (fgets(buffer, sizeof(buffer), fptr) != NULL)
printf("%s", buffer);
putchar('\n');
return 0;
}
如何使用 getline
完成同样的事情?这是一个更概念化的类似问题:
您只需检查 getline(3) - Linux manual page 以确定要传递的适当参数类型和要处理的 return 类型以及 getline
如何指示 success/failure。
然后只需将代码中的 fgets()
替换为 getline()
即可。所有 line-oriented 输入函数读取并包含尾随 '\n'
,因此那里没有变化。但是,请注意 getline()
为您的 buffer
分配存储空间,因此您需要 free()
完成后 buffer
-- 要求您包含 [=21] =] 除了 stdio.h
.
此外,您注意到 getline
不是标准 C 库的一部分。相反,getline
是一个 POSIX 函数,因此并非每个 C 实现都需要提供它,因此您可能会遇到可移植性问题。
基本上就是这样。但是,在您的代码中,您不应使用 硬编码文件名 。这就是 main()
接受参数的原因之一。因此,只需将要读取的文件名作为第一个参数传递给您的程序(如果没有提供参数,您也可以默认从 stdin
读取)
将它们放在一起,作为最低限度的实现,您可以这样做:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv) {
size_t n = 0; /* initial alloc size, 0 - getline decides */
char *buffer = NULL; /* pointer to block of mem holding input */
/* use filename provided as 1st argument (stdin by default) */
FILE *fptr = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fptr) { /* validate file open for reading */
perror ("file open failed");
return 1;
}
/* you pass the address of your buffer and a pointer to n */
while (getline (&buffer, &n, fptr) != -1)
printf("%s", buffer);
putchar('\n');
if (fptr != stdin) /* close file if not stdin */
fclose (fptr);
free (buffer); /* getline allocates, don't forget to free */
return 0;
}
检查一下,如果您还有其他问题,请告诉我。
示例输入文件
$ cat dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
例子Use/Output
$ ./bin/getline_file dat/captnjack.txt
This is a tale
Of Captain Jack Sparrow
A Pirate So Brave
On the Seven Seas.
fgets()/getline()
常用于阅读文本.
不常见的是,输入流包含 空字符 '[=13=]'
.
fgets()
像任何字符一样读取 空字符 。它不会停止读取输入的 行。
以下仅打印到 字符串 中遇到的第一个 空字符 - 它与读取 [=37= 没有区别]空字符和fgets()
添加的附加空字符。
while (fgets(buffer, sizeof(buffer), fptr)) {
printf("%s", buffer); // Maybe stops too early?
}
getline()
,虽然不是标准的 C,但有一个优势,因为它 returns 读取的字符数。然后打印可以打印到返回的计数,而不是仅打印到第一个 空字符 .
size_t n = 0;
char *buffer = NULL;
ssize_t sz;
while ((sz = getline (&buffer, &n, fptr)) != -1) {
fwrite(buffer, 1, sz, stdout);
}
free(buffer);
注:size_t n = 0; char *buffer = NULL;
为初始设置。 getline (&buffer, &n, ...)
接收这两个变量的地址,允许它根据需要更新这两个变量(由于重新分配)。最大缓冲区大小为 SIZE_MAX
或内存池的限制。我们不需要知道它在 getline()
中是如何工作的,因为这是一个不同的实现细节。
虽然 空字符 在简单的文本文件中并不常见,但我发现编写最适合 be prepared for for null characters. They readily come up is reading a text file that is UTF16 encoded. Of course expecting an ASCII or UTF8 文本文件的代码并获得 UTF16 是一个问题,很好地打印想法 空字符 有助于识别问题。