簡體   English   中英

使用系統調用和打印行讀取文件

[英]Reading files using system calls and printing lines

該程序讀取文本文件“ hello.txt”,並在其中查找字符串w的出現,並打印行號和整行。 它還打印出字符串w在文件中出現了多少次。 該程序編譯沒有錯誤,下面是代碼:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>

int main() {

    int fd;
    char c;
    char str[152];
    int i = 0, j = 0;
    int bytesread;
    int flag = 1;
    int found = 0;
    int line = 1;
    int foundflag = 1;

    char w[] = {'h', 'e', 'l', 'l', 'o'};
    int len = strlen(w);

    if ((fd = open("hello.txt", O_RDONLY, 0)) != -1) { //if 1

        bytesread = read(fd, &c, 1);
        str[j] = c;
        j++;

        if (bytesread != -1) { //if 2

            while (bytesread != 0) { //while

                if (c == '\n')
                    line++;

                if (c == w[i]) { //if 3
                    i++;
                    flag = 0;
                } else if (flag == 0 || i == len) //end of f3
                { // else 3
                    i = 0;
                    flag = 1;
                }// end of else 3
                else if (flag == 1) {
                    while (read(fd, &c, 1)) {
                        str[j] = c;
                        j++;
                        if (c == ' ')
                            break;
                        if (c == '\n') {
                            line++;
                            break;
                        }
                    }
                }

                bytesread = read(fd, &c, 1);
                str[j] = c;
                j++;

                if ((c == ' ' || c == '\n') && flag == 0 && i == len) {
                    found++;
                    foundflag = 0;
                    printf("w was found in line %d.\n", line);
                }

                if ((c == '\n')&&(foundflag == 0)) {

                    for (j = 0; str[j] != '\n'; j += 5) {
                        printf("%c", str[j]);

                        if (str[j + 1] != '\n')
                            printf("%c", str[j + 1]);
                        else {
                            j++;
                            break;
                        }

                        if (str[j + 2] != '\n')
                            printf("%c", str[j + 2]);
                        else {
                            j += 2;
                            break;
                        }

                        if (str[j + 3] != '\n')
                            printf("%c", str[j + 3]);
                        else {
                            j += 3;
                            break;
                        }

                        if (str[j + 4] != '\n')
                            printf("%c", str[j + 4]);
                        else {
                            j += 4;
                            break;
                        }
                    }

                    for (; str[j] != '\n'; j++)
                        printf("%c", str[j]);

                    printf("\n");
                    j = 0;

                } else if (c == '\n')
                    foundflag = 1;

            } //end of while
            printf("w has occured %d times.\n", found);

        } else //end of if 2
            printf("couldn't read file.\n");

    } else //end of if 1
        printf("Couldn't open file for read.\n");

    close(fd);
} //end of main

這是終端中的輸出:

w was found in line 1.
hello
w was found in line 2.
w was found in line 6.
hello world
hellooooo
w has occured 3 times.

這是“ hello.txt”的內容:

hello
hello world
hallo
I'm here
we're here
hello
hellooooo

輸出中打印的行數是1,2和6,但這是輸出的樣子:

w was found in line 1.
hello
w was found in line 2.
hello world
w was found in line 6.
hello
w has occured 3 times.
  1. 我建議您閱讀一些C材料。 您的代碼表明您對該語言還不了解。
  2. 我不會更改您的代碼,因為那樣很難。
  3. 我將發布代碼的相關部分並解釋這些內容。

因此,代碼位:

const char fname[] = "hello.txt";
const char w[] = "hello";

(...)    

while (read(fd, &buffer[i], 1) == 1) {
    /* end of line */
    if (buffer[i] == '\n' || buffer[i] == 0x0) {
        buffer[i] = 0;
        if (!strncmp(buffer, w, strlen(w))) {
            printf("w was found in line %d\n", line);
            puts(buffer);
            n++;
        }
        line++;
        i = 0;
        continue;
    }
    i++;
}

說明

  1. while (read(fd, &buffer[i], 1) == 1) :這將從您的fd讀取一個字符(該字符由先前的open調用返回),並將其存儲在buffer [i]中。 這里要注意的相關事情是,在此之前,您應該聲明int i = 0並確保buffer是已定義的數組或已malloc內存區域。 while直到字節讀取量小於1(這正是我們要求)不同仍將繼續。

  2. if (buffer[i] == '\\n' || buffer[i] == 0x0)if檢測到行尾。 非常簡單。

  3. buffer[i] = 0; 並且if (!strncmp(buffer, w, strlen(w)))buffer[i] = 0會將當前緩沖區的最后一個字符設置為零。 這是因為它擺脫了我們閱讀的最后一個\\n ,因此我們可以使用puts很好地打印它。 我在評論中建議的一點是使用strncmp 此函數就像strcmp一樣,但是最多只能比較定義的字節數。 因此,使用此功能,您可以有效地確定字符串是否以要查找的子字符串開頭。 如果找到了此字符串,我們將打印該行所在的行,打印緩沖區本身,並遞增n ,這是我們找到w次數的計數器。 您應該已經聲明int n = 0; 在代碼的開頭...

  4. line++; i = 0; continue; :這是結束線檢測內部if 因此,它的作用是增加行計數器,將i設置為零-這很重要,因為在新行中,我們將讀取一個新的緩沖區,並且該緩沖區索引必須從0開始。 continue強制循環重復而不執行其余代碼。

  5. 最后, while范圍的其余部分定義為i++ 由於while循環在每個字符處執行,因此每次讀取字符后,緩沖區索引必須增加。


我測試的文件就是您提供的文件。 我得到的輸出是:

w was found in line 1
hello
w was found in line 2
hello world
w was found in line 6
hello
w was found 3 times

暫無
暫無

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

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