c - 使用 C 中的 Unix 系统调用计算文件中的总行数

标签 c linux unix

我是C语言的初学者,对unix没有太多经验。我试图使用 unix 系统调用来计算文件内的总行数,但没有得到任何结果。我的 lineCount 总是显示为 0 我不知道为什么?如果可能的话,我希望有人帮我计算行数。谢谢

int lineCount = 0;
while (*buffer != '\0') // to check the end of the file
{
    read( in_fd, buffer, BUFFERSZ);
    if (*buffer == '\n')
    {
       lineCount++;
    }
}

printf("Linecount: %i \n", lineCount );

最佳答案

open 合作, readwrite ,与使用 fopen 确实没有太大区别。 , fread ,和fwrite (或 fgetsfprintf )除了您承担的任何转换、字节计数和设置创建的文件权限位的负担。当write写入一个值,例如 1020到一个文件,它正在写入 bytes 的数量您告诉它写入,该数字将以与您的硬件使用相同的字节序存在于文件中。

例如,如果您有 unsigned v = 1020; (0x3fc 十六进制)然后 write (fd, &v, sizeof v); ,当您使用 hexdump 查看文件时或od (或类似的),它将包含 fc 03 00 00 (假设您的硬件是小端)。这些是你的4-bytesunsigned1020 。您无法在文本编辑器中打开该文件并期望看到 ASCII 字符,因为这不是写入文件的内容。

使用 open 查找文件中的行数和read ,你基本上想要open文件,一次将文件读入缓冲区一些合理的字节数,并计算 '\n'文件中的字符。

(注意:您还需要检查从文件中读取的最后一个字符是否不是 '\n' 。如果是,您需要将 +1 添加到您的行中-count 来计算最后一行的非 POSIX 行末尾。)

唯一的其他警告是注意 mode (权限)任何新创建的文件 open用于写作。否则,您将发现自己无法访问新创建的文件。这就是为什么 open 提供 mode_t mode作为本例中的第三个参数 O_CREAT提供了标志。

如果您打算坚持只使用 open, read, write对于您的程序 I/O,那么您必须向终端提供错误消息输出 STDERR_FILENO如果发生错误。您可能需要一个简短的帮助函数来为此目的写入字符串消息。

将各个部分放在一起,您可以在忠于自己的事业的同时执行以下操作。以下代码采用 infileoutfile名称作为程序的前两个参数,读取 infile 65K bytes一次计算 '\n' s 文件中,然后将结果写入 outfile考虑文件的任何非 POSIX 行结尾。 writeliteral提供错误消息的帮助程序:

#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

enum { BUFFERSZ = 1 << 16 };    /* 65K buffer size */

void writeliteral (int fildes, const char *s);

int main (int argc, char **argv) {

    if (argc < 3) {
        writeliteral (STDERR_FILENO, "error: insufficient input.\n");
        writeliteral (STDERR_FILENO, "usage: progname infile outfile\n");
        return 1;
    }

    char buf[BUFFERSZ] = "";
    unsigned  i = 0, nlines = 0;
    ssize_t n = 0;
    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
    int fd = open (argv[1], O_RDONLY);

    if (fd == -1) {               /* validate file open for reading */
        writeliteral (STDERR_FILENO, "error: infile open failed.\n");
        return 1;
    }

    while ((n = read (fd, buf, sizeof buf)) > 0)  /* read 65k chars */
        for (i = 0; i < n; i++)            /* count newlines in buf */
            if (buf[i] == '\n')
                nlines++;
    if (buf[i - 1] != '\n')       /* account for non-POSIX line end */
        nlines++;

    close (fd); /* close file */

    /* open outfile for writing, create if it doesn't exist */
    if ((fd = open (argv[2], O_WRONLY | O_CREAT, mode)) == -1) {
        writeliteral (STDERR_FILENO, "error: outfile open failed.\n");
        return 1;
    }
    write (fd, &nlines, sizeof nlines);  /* write nlines to outfile */

    close (fd); /* close file */

    return 0;
}

/** write a string literal to 'fildes' */
void writeliteral (int fildes, const char *s)
{
    size_t count = 0;
    const char *p = s;

    for (; *p; p++) {}
    count = p - s;

    write (fildes, s, count);
}

输入文件示例

$ nl -ba ../dat/captnjack.txt
     1  This is a tale
     2  Of Captain Jack Sparrow
     3  A Pirate So Brave
     4  On the Seven Seas.

示例使用/输出

$ ./bin/readwrite_lineno ../dat/captnjack.txt ../dat/jacklines.dat
$ hexdump -n 16 -C ../dat/jacklines.dat
00000000  04 00 00 00                                       |....|
00000004

请仔细查看,如果有任何问题请告诉我。它向您展示了为什么您可能会欣赏 printf完成后,函数系列格式说明符甚至更多。

关于c - 使用 C 中的 Unix 系统调用计算文件中的总行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38155730/

相关文章:

python - 快速远程登录系统?

linux - 为什么 GCC(和其他工具)不遵循 GNU 命令选项约定准则?

linux - 在文本文件中查找行号 - 无需打开文件

c - 指数数在 C 中如何工作

c - 在 c 中访问 bash 局部变量

file - 将多个目录中相同类型的所有文件上移一个文件夹

android - 当前目录上的符号链接(symbolic link)级别太多?

linux - 使用文件计数列出文件夹的 UNIX 命令

c - 简单的弹性程序

c - 如何减慢 glutIdleFunc 动画速度