问题
I want to copy a file with skipping first n of its lines and last m lines using open, read, write and lseek
(eg. n = 1, m = 2, source file:
AAAAAAA
BBBBBBB
CCCCCCC
DDDDDDD
dest file:
BBBBBBB )
I know how to copy a file but don't know how to skip the lines. Here is my code for copy:
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);
How can i solve this problem?
回答1:
You should use fgets
to read your file since that will read it line by line.
Because it is not trivial to say how many lines you have in total I would suggest you
- use
fgets
to read the file line by line - skip outputting the first
n
lines - write the rest to your output files and count the number of lines and remember the length of each.
- use
ftruncate
to truncate off the lastm
lines.
This should do the trick:
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);
}
来源:https://stackoverflow.com/questions/19447627/copy-file-skipping-first-n-lines-and-last-m-lines