在C中读取和打印.txt文件行的最清晰方法

Dli*_*net 8 c file-io printf scanf file-read

有很多方法描述如何使用各种方法在此站点上打印文本文件的行:

它们似乎都是根据具体的例子量身定制的.

如果能够使用最清晰,最简洁,最简单的方法,那就太棒了:将任何文本文件的每一行打印到屏幕上.优选地详细说明每条线的作用.

简洁明了的要点.

Jon*_*ler 9

#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);
}
Run Code Online (Sandbox Code Playgroud)

cat()功能并非绝对必要,但我宁愿使用它.主程序逐步执行每个命令行参数并打开命名文件.如果成功,则调用该cat()函数来打印其内容.由于调用fopen()未指定"rb",因此将其作为文本文件打开.如果文件未打开,则此代码将无提示地忽略该问题.如果未指定文件,则根本不打印任何文件.

cat()函数一次只读取最多4096个字节的文本块,并将它们写入标准输出("屏幕").当没有更多要阅读时它会停止.

如果要在未指定文件时将代码扩展为读取标准输入,则可以使用:

if (argc == 1)
    cat(stdin);
else
{
    ...while loop as now...
}
Run Code Online (Sandbox Code Playgroud)

这是使cat()函数如图所示编写的原因之一.

此代码不直接关注换行符 - 或任何类型的行.如果你想一次正式处理一行,那么你可以做几件事:

static void cat(FILE *fp)
{
    char buffer[4096];
    while (fgets(buffer, sizeof(buffer), fp) != 0)
         fputs(buffer, stdout);
}
Run Code Online (Sandbox Code Playgroud)

这将一次读写一行.如果任何行超过4095字节,它将在两个或多个操作中读取该行并将其写入相同数量的操作.请注意,这假定文本文件的版本使用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);
}
Run Code Online (Sandbox Code Playgroud)

此版本也不会处理二进制数据(意味着其中包含空字节的数据).当然可以升级它来这样做:

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);
}
Run Code Online (Sandbox Code Playgroud)

getline()函数报告它读取了多少字节(之后有一个空字节),但该fwrite()函数是唯一一个获取任意字节流并将它们全部写入给定流的函数.

  • @Dlinet,这是非常优秀的C代码.Python可以用更少的行来解决这个问题,但这是因为Python是一种比C更高级的语言.对于像这样的简单问题,Python的优点是; 但是C让经验丰富的开发人员可以完全控制完成的工作以及完成工作的方式.Python可以用更少的行来解决这个问题......但Python是用C语言编写的!(好吧,CPython无论如何.还有其他类型的Python.但CPython排在第一位,仍然是王道.) (2认同)