[英]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.
因此,代碼位:
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++;
}
while (read(fd, &buffer[i], 1) == 1)
:這將從您的fd
讀取一個字符(該字符由先前的open
調用返回),並將其存儲在buffer [i]中。 這里要注意的相關事情是,在此之前,您應該聲明int i = 0
並確保buffer
是已定義的數組或已malloc
內存區域。 這while
直到字節讀取量小於1(這正是我們要求)不同仍將繼續。
if (buffer[i] == '\\n' || buffer[i] == 0x0)
: if
檢測到行尾。 非常簡單。
buffer[i] = 0;
並且if (!strncmp(buffer, w, strlen(w)))
: buffer[i] = 0
會將當前緩沖區的最后一個字符設置為零。 這是因為它擺脫了我們閱讀的最后一個\\n
,因此我們可以使用puts
很好地打印它。 我在評論中建議的一點是使用strncmp 。 此函數就像strcmp
一樣,但是最多只能比較定義的字節數。 因此,使用此功能,您可以有效地確定字符串是否以要查找的子字符串開頭。 如果找到了此字符串,我們將打印該行所在的行,打印緩沖區本身,並遞增n
,這是我們找到w
次數的計數器。 您應該已經聲明int n = 0;
在代碼的開頭...
line++; i = 0; continue;
:這是結束線檢測內部if
。 因此,它的作用是增加行計數器,將i
設置為零-這很重要,因為在新行中,我們將讀取一個新的緩沖區,並且該緩沖區索引必須從0開始。 continue
強制循環重復而不執行其余代碼。
最后, 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.