0

我想复制一个文件,使用 open、read、write 和 lseek 跳过它的前 n 行和最后 m 行(例如 n = 1,m = 2,源文件:
AAAAAAA
BBBBBBB
CCCCCCC
DDDDDDD

目标文件:
BBBBBBB)

我知道如何复制文件,但不知道如何跳过这些行。这是我的复制代码:

    char buf[128];
    size_t size;

    int source = open(argv[1], O_RDONLY);
    int dest = open(argv[2], O_CREAT | O_APPEND | O_WRONLY);

    if(source == -1) {
            printf("error");
            return;
    }
    if(dest == -1) {
            printf("error");
            return;
    }

    while((size = read(source, buf, sizeof(buf))) > 0) {
            write(dest, buf, size);
    }

    close(source);
    close(dest);

我怎么解决这个问题?

4

1 回答 1

2

您应该使用fgets来读取您的文件,因为它将逐行读取。

因为要说出你总共有多少行我建议你

  • 用于fgets逐行读取文件
  • 跳过输出第一n
  • 将其余部分写入输出文件并计算行数并记住每行的长度。
  • 用于ftruncate截断最后m一行。

这应该可以解决问题:

void copy_nm(char * source, char * dest, int n, int m) {
    FILE * in = fopen(source, "r");
    FILE * out = fopen(dest, "w");

    size_t file_length = 0;
    size_t line_lengths[m + 1];
    memset(line_lengths, 0 , sizeof(line_lengths));

    int lengths_iterator = 0;


    char buffer[0x400];

    while (fgets(buffer, sizeof(buffer), in)) {
        size_t length = strlen(buffer);

        if (n) { // skip this line
            if (buffer[length - 1] == '\n') // only if it is a real line
                n--;
            continue;
        }

        fwrite(buffer, length, 1, out);
        line_lengths[lengths_iterator] += length;
        file_length += length;

        if (buffer[length - 1] != '\n') { // line was longer then the buffer
            continue;
        }

        lengths_iterator++;
        lengths_iterator %= m+1;

        line_lengths[lengths_iterator] = 0;
    }

    for (lengths_iterator = 0; lengths_iterator < m+1; lengths_iterator++) {
        file_length -= line_lengths[lengths_iterator];
    }

    fseek(out, 0, SEEK_SET); // rewind before truncating
    ftruncate(fileno(out), file_length);

}
于 2013-10-18T10:44:20.360 回答