所以我試圖創建一個函式 print_file_rows() 來列印檔案的前十行。如果檔案有超過 10 行,它作業得很好,但如果有 10 行或更少,它就會開始列印垃圾。關于如何解決這個問題的任何想法?(必須只使用系統功能打開/讀取/寫入/關閉)
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
void print_file_rows(char *path)
{
int fd = open(path, O_RDONLY);
if (fd < 0)
{
return NULL;
}
size_t size = 100;
size_t offset = 0;
size_t res;
char *buff = malloc(size);
while((res = read(fd, buff offset, 100)) != 0)
{
offset = res;
if (offset 100 > size)
{
size *= 2;
buff = realloc(buff, size);
}
}
close(fd);
int j = 0;
for(int i = 0;buff[i] != '\0'; i )
{
if(j == 10)
{
break;
}
if(buff[i] == '\n')
{
j ;
}
printf("%c", buff[i]);
}
free(buff);
}
int main()
{
print_file_rows("a.txt");
return 0;
}
uj5u.com熱心網友回復:
您不需要任何緩沖區。它很可能在作業系統級別緩沖,因此您可以逐個字符列印。
int print_file_rows(char *path, size_t nrows)
{
int result = -1;
int fd = open(path, O_RDONLY);
char c;
if (fd > 0)
{
while(nrows && read(fd, &c, 1) == 1)
{
write(STDOUT_FILENO, &c, 1);
if(c == `\n`) nrows--;
}
result = nrows;
}
close(fd);
return result;
}
int main()
{
if(print_file_rows("a.txt", 10) == -1)
printf("Something has gone wrong\n");
return 0;
}
uj5u.com熱心網友回復:
來自man 2 read:
概要
#include <unistd.h> ssize_t read(int fd, void *buf, size_t count);描述 read() 嘗試從檔案描述符 fd 讀取多達 count 個位元組到緩沖區中,從 buf 開始。
read用于讀取原始位元組,因此沒有strings 的概念。它不會'\0'在緩沖區的末尾放置一個 NUL 終止位元組 ( )。如果要將讀取的資料視為字串,則必須自己終止緩沖區。
為了給這個 NUL 終止位元組騰出空間,你應該總是在你的緩沖區中分配一個額外的位元組(即,比你的最大值少讀一個位元組)。
我們可以看到回傳值實際上是型別ssize_t,而不是size_t,這允許
出錯時,回傳 -1,并設定 errno 以指示錯誤。
這意味著我們需要檢查回傳值是否大于零,而不是不為零,否則會導致偏移量在出錯時遞減。
盡管如此,請注意昨天發布的一個類似問題的答案顯示了如何在不使用動態緩沖區的情況下實作這一目標。您可以簡單地一次讀取一個位元組,并在遇到 10 個換行符時停止讀取。
如果您確實想了解如何將檔案讀入動態緩沖區,那么這里有一個示例,使用計算offset到 NUL 在緩沖區增長時終止緩沖區。請注意,以這種方式讀取整個檔案對于此任務(尤其是大檔案)來說效率低下。
(注意:呼叫write, 而不是printf)
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
void print_file_rows(const char *path)
{
int fd = open(path, O_RDONLY);
const size_t read_size = 100;
size_t size = read_size;
size_t offset = 0;
ssize_t res;
char *buff = malloc(size 1);
while ((res = read(fd, buff offset, read_size)) > 0) {
offset = res;
buff[offset] = '\0';
if (offset read_size > size) {
size *= 2;
buff = realloc(buff, size 1);
}
}
close(fd);
int lines = 0;
for (size_t i = 0; lines < 10 && buff[i] != '\0'; i ) {
write(STDOUT_FILENO, &buff[i], 1);
if (buff[i] == '\n')
lines ;
}
free(buff);
}
int main(void)
{
print_file_rows("a.txt");
}
(為了代碼簡潔malloc,省略了錯誤處理。、realloc和open都可能失敗,通常應該處理。)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/351593.html
上一篇:為什么我在嘗試使用fin2.seekg(-2*sizeof(int),ios::cur)從末尾到中間讀取檔案時出現奇怪的錯誤;?沒有字串
