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

我试图获取read()系统调用来逐行读取我的文件,并将每一行都反转为stdout。我的问题是让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,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;
}
tbdys 回答:使用read()系统调用反转文件中的每一行

当您说“通常它只是读取整个文件”时,我不确定您的意思。 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,'\n')) < end );
                assert(eol == end);
                assert(eol[-1] != '\n' || s == end);

                fwrite(prev,1,s - prev,stdout);
                prev = buf + BUFSIZ - (end - s);
                memcpy(prev,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,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;
}
本文链接:https://www.f2er.com/3162922.html

大家都在问