簡體   English   中英

在 C 中使用 Unix 系統調用計算文件中的總行數

[英]To count the total number of lines in a file using Unix system call in C

我是 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 );

使用openreadwrite與使用fopenfreadfwrite (或fgetsfprintf )實際上沒有太大區別,除了任何轉換、字節計數和設置創建的文件權限位的負擔都在你身上。 write將諸如1020的值寫入文件時,它正在寫入您告訴它寫入的bytes數,並且該數字將以與您的硬件使用的相同字節順序存在於文件中。

例如,如果您有unsigned v = 1020; ( 0x3fc in hex) 然后write (fd, &v, sizeof v); , 當您使用hexdumpod (或類似)查看您的文件時,它將包含fc 03 00 00 (假設您的硬件是小端)。 這些是您的4-bytes unsigned1020 您無法在文本編輯器中打開文件並期望看到 ASCII 字符,因為這不是寫入文件的內容。

要使用openread查找文件中的行數,您基本上要open文件,將文件一次讀入緩沖區一些合理數量的字節並計算文件中的'\\n'字符。

注意:您還需要檢查從文件中讀取的最后一個字符是否不是'\\n' 。如果是,您需要將+1添加到您的行數以考慮非 POSIX 行最后一行的結尾。)

唯一的其他警告是注意您open用於寫入的任何新創建文件的mode (權限)。 否則,您會發現自己無法訪問新創建的文件。 這就是為什么在提供O_CREAT標志的情況下 open 提供mode_t mode作為第三個參數的原因。

如果您打算堅持只對程序 I/O 使用open, read, write ,那么您將必須在出現錯誤時向終端STDERR_FILENO提供錯誤消息輸出。 您可能需要一個簡短的輔助函數來為此目的編寫字符串消息。

將各個部分放在一起,您可以在忠於自己的事業的同時執行以下操作。 以下代碼將infileoutfile名稱作為程序的前兩個參數,一次讀取infile 65K bytes ,計算文件中的'\\n'數,然后將結果寫入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系列函數格式說明符。

您的代碼只檢查*buffer的換行符,這是您讀取的每個BUFFERSZ塊的第一個字符,即您的代碼甚至不查看大部分輸入。 (它也不會正確檢查文件結尾:您需要查看read的返回值。)

這是一個使用read模擬fgetc的簡單解決方案:

size_t lines = 0;
char c;
while (read(in_fd, &c, 1) == 1) {
    if (c == '\n') {
        lines++;
    }
}

printf("Linecount: %zu\n", lines);

如果您也不能使用printf ,一個快速的解決方法是:

static void print_n(size_t n) {
    if (n / 10) {
        print_n(n / 10);
    }
    char c = '0' + n % 10;
    write(1, &c, 1);
}

...
write(1, "Linecount: ", strlen("Linecount: "));
print_n(lines);
write(1, "\n", 1);

參考: 使用C計算行數使用代碼

FILE *fp = fopen("myfile.txt");
 int ch; 
int count=0;
 do { ch = fgetc(fp); 
if( ch== '\n')
 count++;
 }while( ch != EOF ); 
printf("Total number of lines %d\n",count);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM