本网站有多种方法来描述如何使用各种方法打印文本文件的行:
它们似乎都是为特定的示例量身定制的。
最好有一种最清晰、最简洁、最容易的方法来将任何文本文件的每一行打印到屏幕上,最好附有每行代码的详细说明。
注重简洁和清晰度。
本网站有多种方法来描述如何使用各种方法打印文本文件的行:
它们似乎都是为特定的示例量身定制的。
最好有一种最清晰、最简洁、最容易的方法来将任何文本文件的每一行打印到屏幕上,最好附有每行代码的详细说明。
注重简洁和清晰度。
#include <stdio.h>
static void cat(FILE *fp)
{
char buffer[4096];
size_t nbytes;
while ((nbytes = fread(buffer, sizeof(char), sizeof(buffer), fp)) != 0)
fwrite(buffer, sizeof(char), nbytes, stdout);
}
int main(int argc, char **argv)
{
FILE *fp;
const char *file;
while ((file = *++argv) != 0)
{
if ((fp = fopen(file, "r")) != 0)
{
cat(fp);
fclose(fp);
}
}
return(0);
}
cat()
函数并不是必需的,但我更喜欢使用它。主程序遍历每个命令行参数并打开指定的文件。如果成功,它将调用cat()
函数以打印其内容。由于对fopen()
的调用没有指定"rb"
,因此它被打开为文本文件。如果文件未打开,则此代码会静默忽略该问题。如果没有指定文件,则根本不会打印任何内容。
cat()
函数只是简单地每次读取最多4096个字节的文本块,并将它们写入标准输出('屏幕')。当没有更多内容可读时,它就会停止。if (argc == 1)
cat(stdin);
else
{
...while loop as now...
}
cat()
函数的原因之一。
此代码不直接关注换行符或任何类型的行。如果您想以正式方式逐行处理它,则可以采取几种方法:
static void cat(FILE *fp)
{
char buffer[4096];
while (fgets(buffer, sizeof(buffer), fp) != 0)
fputs(buffer, stdout);
}
fread()
和fwrite()
的版本不是这样的。在POSIX系统上,使用fread()
和fwrite()
的版本将处理数据中带有空字节('\0'
)的任意二进制文件,但使用fgets()
和fputs()
的版本不会。到目前为止,两个版本都是严格的标准C(任何版本的标准),因为它们不使用任何特定于平台的扩展;它们是代码可移植性最强的。
或者,如果您拥有POSIX 2008 getline()
函数,则可以使用它,但您还需要#include <stdlib.h>
(因为您最终必须释放它分配的内存):
static void cat(FILE *fp)
{
char *buffer = 0;
size_t buflen = 0;
while (getline(&buffer, &buflen, fp) != -1)
fputs(buffer, stdout);
free(buffer);
}
这个版本也无法处理二进制数据(即其中包含空字节的数据)。当然可以升级以实现该功能:
static void cat(FILE *fp)
{
char *buffer = 0;
size_t buflen = 0;
ssize_t nbytes;
while ((nbytes = getline(&buffer, &buflen, fp)) != -1)
fwrite(buffer, sizeof(char), nbytes, stdout);
free(buffer);
}
< p > getline()
函数会报告它读取了多少字节(之后有一个空字节),但是 fwrite()
函数是唯一的函数,它可以将任意字节流写入给定的流中。
fread()
和fwrite()
的版本也可以处理任意二进制文件;其他版本假设字符串中没有嵌入空字节'\0'
。代码实际上做出了很少的假设。 - Jonathan Leffler好的,这里是我最终完成的非常简短的解决方案。我想如果没有根本性的错误,否则它不会被建议,但我想我会在这里发布它,并希望有人能够批判它:
#include <stdio.h>
main()
{
FILE *MyFile;
int c;
MyFile=fopen("C:\YourFile.txt","r");
c = fgetc(MyFile);
while (c!=EOF)
{
printf("%c",c);
c = fgetc(MyFile);
}
}
fopen()
的返回值之前,没有检查文件是否打开成功;(3)您对于main()
的声明不符合C99或C2011的规范——应该是 int main(void)
或 int main(int argc, char **argv)
(或者,在紧急情况下, int main()
);(4)最好使用putchar()
或fputc()
而不是使用printf()
来输出单个字符;(5)更符合C语言习惯的方式是使用while((c = fgetc(MyFile)) != EOF) putchar(c);
;(6)缺少fclose(MyFile)
。 - Jonathan Lefflerint c;
的正确且重要的做法。严格来说,由于您为 main()
编写了 C89 定义,因此应在 main()
结尾处使用 return(0);
(带或不带括号)。如果您的代码符合 C99 标准,则可以不使用它,但在我看来,即使在 C99 或 C2011 代码中也最好包含它。 - Jonathan Lefflercat
),然后转向更高级的内容。他们不仅教授了如何组织这种程序的重要课程,还涵盖了语言设计问题。(Pascal中存在一些真正困扰他们的问题,如果你了解C,你会意识到C没有这些问题。)http://www.amazon.com/Software-Tools-Pascal-Brian-Kernighan/dp/0201103427
学习本书中的程序并在C语言中实现它们将是一次很好的教育练习。任何Linux系统已经拥有更强大和完全调试过的这些程序版本,但是通过学习本书并学会编写这些内容不会浪费你的时间。
或者,您可以在计算机上安装FreePascal并使用它来运行本书中的程序。
祝你好运,并且永远享受软件开发!
如果你想要一些预先准备好的东西,在 POSIX 系统上有 cat
。
如果你想自己写,这是基本布局:
关键是,没有真正特定的方法来做到这一点。只需读取,然后写入,并重复。通过一些错误检查,你就可以再次使用 cat。