将文件写入.c中的另一个文件

时间:2016-04-14 10:06:27

标签: c linux file

我有一个代码读取文件,然后将其内容复制到另一个文件。我需要让它只复制每20个符号,然后跳过10个符号,然后再跳过20个符号,依此类推。

我必须使用lseek()函数,但我不知道如何在循环中完成所有这些操作。

main (argc, argv)
int argc;
char *argv[];
{
    int fd1, fd2;
    int nbytes, mode;
    char buf[BUFSIZ];
    if(argc<3){
        fprintf(stderr, "%s: nepareizs kopesanas parametrs\n", argv[0]);
        exit(1);
    }
    if((fd1 = open(argv[1], O_RDONLY)) < 0){
        fprintf(stderr, "Nevar atvert failu %s\n", argv[1]);
        exit(1);
    }
    if((fd2 = open(argv[2], O_WRONLY | O_CREAT, mode))<0){
        fprintf(stderr, "Nevar izveidot jaunu failu %s\n", argv[2]);
        exit(1);
    }

    nbytes = lseek(fd1, 10, 0)
    while((nbytes = read(fd1, buf, BUFSIZ))>0){
            if(write(fd2, buf, nbytes) < 0){
                fprintf(stderr, "не понимаю\n");
                break;

            }

    }

    if (nbytes<0)
        fprintf(stderr, "не понимаю\n");
    close(fd1);
    close(fd2);
    exit(0);
}

2 个答案:

答案 0 :(得分:1)

替换

nbytes = lseek(fd1, 10, 0)
while((nbytes = read(fd1, buf, BUFSIZ))>0){
        if(write(fd2, buf, nbytes) < 0){
            fprintf(stderr, "не понимаю\n");
            break;

        }

}

while((nbytes = read(fd1, buf, BUFSIZ))>0){
        /* first you write your 20 bytes */
        if(write(fd2, buf, nbytes) < 0){
            fprintf(stderr, "не понимаю\n");
            break;

        }
        /* and then you move 10 bytes further */
        if (lseek(fd1, 10, 0) < 0){
            /* break if this is the eof */
            break;
        }

}

如果BUFSIZ是20。

或最简单,BUFSIZ = 30:

while((nbytes = read(fd1, buf, BUFSIZ))>0){
    /* you only write the first 20 read bytes, or nbytes
       if there are no much bytes in the buffer */
    if(write(fd2, buf, nbytes < 20 ? nbytes : 20) < 0){
        fprintf(stderr, "не понимаю\n");
        break;
    }
}

答案 1 :(得分:0)

另一种考虑的替代方案。您的问题的评论中提到了许多好处。下面的示例收集了各种注释,并提供了一种简洁的方法来读取30个字节并将前20个字节写入输出文件。

避免使用所有幻数(遍及代码的硬编码值)。验证读取和写入,使用流操作(例如freadfwrite)而不是readwrite)和输出的close文件已经过验证:

#include <stdio.h>

enum { WRTSZ = 20, BUFSZ = 30 };

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

    if (argc < 3 ) {
        fprintf (stderr, "error: insufficient input, usage: %s ifile ofile\n",
                argv[0]);
        return 1;
    }

    FILE *ifp = fopen (argv[1], "rb");
    FILE *ofp = fopen (argv[2], "w+");
    char buf[BUFSZ] = "";

    if (!ifp) { /* validate file open for reading (binary) */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }
    if (!ofp) { /* valdate file open for writing */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }
    /* read BUFSZ bytes (require at least WRTSZ), and output */
    while (fread (buf, sizeof *buf, BUFSZ, ifp) >= WRTSZ)
        if (fwrite (buf, sizeof *buf, WRTSZ, ofp) != WRTSZ)
            fprintf (stderr, "error: fwrite of WRTSZ failed.\n");

    fclose (ifp);
    if (fclose (ofp))   /* validate close of output file */
        fprintf (stderr, "error: on close of '%s'.\n", argv[2]); 

    return 0;
}

注意:只写入完整的20字节块。如果最后一次读取的部分读取少于20字节,则该信息不会写入输出文件。您可以调整freadfwrite周围的条件,以根据您的需要定制行为。)

示例输入文件(非POSIX,没有eol)

以下输入文件是用于示例目的的文本,它不包含POSIX 行尾'\n')。 (如果您愿意,可以包含换行符,只会导致换行符被写入输出文件)

$ cat dat/ruler.txt
........10........20........30........40........50........60........70........80........90

使用/输出文件

$ ./bin/rd30wrt20 dat/ruler.txt dat/rulerout.txt
$ cat dat/rulerout.txt
........10........20........40........50........70........80

仔细看看,如果您有任何问题,请告诉我。

写入所有字节(0 <部分字节&lt; = WRTSZ)

如果要编写在上一个fread期间读取的任何部分字节,可以将条件调整为类似于以下内容:

size_t rdsz;
...
/* read BUFSZ bytes, write 0 < rdsz <= WRTSZ */
while ((rdsz = fread (buf, sizeof *buf, BUFSZ, ifp)))
    if (fwrite (buf, sizeof *buf,
        rdsz > WRTSZ ? WRTSZ : rdsz, ofp) != WRTSZ)
        fprintf (stderr, "warning: fwrite of '%zu'.\n", rdsz);