gpt4 book ai didi

c - 使用 read() 系统调用反转文件中的每一行

转载 作者:行者123 更新时间:2023-11-30 19:25:29 25 4
gpt4 key购买 nike

我试图让 read() 系统调用逐行读取我的文件并将每一行反转到标准输出。我的问题是让 read() 逐行读取我的文件,因为通常它只读取整个文件。我希望 LINE_BUFFER 大小为一行的最大大小。

我尝试实现一个函数来尝试执行此操作,但它似乎破坏了程序,并且我对如何解决此问题有点迷失。

这是我的代码:

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

#define LINE_BUFFER 1024

int charCount(const char *name1);
ssize_t readline (char *buf, size_t a, int b, off_t *offset);

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

if(argc ==2){
charCount(argv[1]);
}else{
printf("Provide a file\n");
}
return 0;
}

int charCount(const char *name1)
{
char buffer[LINE_BUFFER];
int fd;
ssize_t len = 0;
int nread;
int i = 0;
off_t offset = 0;
if ((fd = open(name1, O_RDONLY)) == -1)
{
perror("Error in opening file");
return (-1);
}

int size = lseek(fd,-1, SEEK_END);

while(size>=0)
{
while((len = readline(buffer,LINE_BUFFER,fd,&offset)) != -1){
write(1,buffer,1);
lseek(fd, -2,SEEK_CUR);
size--;
}
}
close(fd);
return(0);
}

ssize_t readline(char *buf, size_t a, int b, off_t *offset)
{
int fd;

ssize_t nchr =0;
ssize_t idx =0;
char *p = NULL;

if ((nchr = lseek(fd, *offset, SEEK_SET)) != -1){
nchr = read(fd,buf,a);
}

p = buf;
while(idx<nchr && *p != '\n') p++,idx++;
*p =0;

if(idx == nchr) {
*offset + nchr;
return nchr < (ssize_t)a ? nchr : 0;
}

*offset += idx+1;
return idx;
}

最佳答案

当你说“通常它只是读取整个文件”时,我不确定你的意思是什么。 read 读取的最大大小相当低,通常为 4KiB 或 8KiB。无论如何,我整理了一些代码来反转文件的行。

#include <assert.h>
#include <fcntl.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int xopen(const char *, int);
void * Realloc(void *, size_t);
void reverse(char *, char *);
char * findchr(char *, char *, char);

int
main(int argc, char **argv)
{
ssize_t rc;

size_t siz = BUFSIZ; /* size available to read into */
char *buf = Realloc(NULL, BUFSIZ + siz); /* Pad the front */
char *s = buf + BUFSIZ; /* first char of a line */
char *prev = s; /* start of data from previous read */
char *end = s; /* one past last char read from input */
int fd = argc > 1 ? xopen(argv[1], O_RDONLY) : STDIN_FILENO;

while(( rc = read( fd, s, BUFSIZ )) > 0 ) {
char *eol; /* A newline, or one past valid data */
end = s + rc;

if( (eol = findchr(s, end, '\n')) == end ) {
/* No newlines found in the last read. Read more. */
if( end > buf + siz ) {
ptrdiff_t e_off = end - buf;
ptrdiff_t p_off = prev - buf;
siz += BUFSIZ;
buf = Realloc(buf, BUFSIZ + siz);
eol = end = buf + e_off;
prev = buf + p_off;
}
s = end;
assert( s <= buf + siz );
continue;
}
s = prev;
do {
assert(*eol == '\n');
assert(eol < end);
reverse(s, eol-1);
s = eol + 1;
assert(s <= end);
} while( (eol = findchr(s, end, '\n')) < end );
assert(eol == end);
assert(eol[-1] != '\n' || s == end);

fwrite(prev, 1, s - prev, stdout);
prev = buf + BUFSIZ - (end - s);
memcpy(prev, s, end - s);
eol = s = buf + BUFSIZ;
}
if(rc == -1) {
perror(argc > 1 ? argv[1] : "stdin");
return EXIT_FAILURE;
}
if(prev < s) {
reverse(prev, s-1);
fwrite(prev, 1, s - prev, stdout);
}

return EXIT_SUCCESS;
}

/*
* Find v between str and end. If not found,
* return end. (This is basically strchr, but
* doesn't care about nul.)
*/
char *
findchr(char *str, char *end, char v) {
assert(str <= end);
while( str < end && *str != v )
str += 1;
return str;
}

void
reverse(char *start, char *end)
{
for( ; start < end; start++, end-- ) {
char tmp = *end;
*end = *start;
*start = tmp;
}
}


void *
Realloc( void *buf, size_t s )
{
buf = realloc( buf, s );
if( buf == NULL) { perror("realloc"); exit(EXIT_FAILURE); }
return buf;
}

int
xopen(const char *path, int flag)
{
int fd = open(path, flag);
if( fd == -1 ) { perror(path); exit(EXIT_FAILURE); }
return fd;
}

关于c - 使用 read() 系统调用反转文件中的每一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58703051/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com