Skip to content

Instantly share code, notes, and snippets.

@thammi
Created October 21, 2012 13:35
Show Gist options
  • Save thammi/3926956 to your computer and use it in GitHub Desktop.
Save thammi/3926956 to your computer and use it in GitHub Desktop.
Reverse a file
#include <stdio.h>
#include <unistd.h>
#define BLOCK_SIZE 512
#define min(a, b) ((a) < (b) ? (a) : (b))
inline void swap(char* buf, size_t a, size_t b) {
char tmp = buf[a];
buf[a] = buf[b];
buf[b] = tmp;
}
static int reverse(FILE* in, FILE* out) {
// not reentrant but faster than without 'static'
static char buf[BLOCK_SIZE];
// TODO: check return value
fseek(in, 0, SEEK_END);
long file_left = ftell(in);
while(file_left > 0) {
size_t cur_block = min(BLOCK_SIZE, file_left);
size_t buf_filled = 0;
// TODO: check return value
fseek(in, -cur_block, SEEK_CUR);
// make sure we read a full block
do {
ssize_t now_read = fread(buf + buf_filled, sizeof(char), cur_block - buf_filled, in);
buf_filled += now_read;
if(now_read <= 0) {
return 1;
}
} while(buf_filled < cur_block);
// TODO: check return value
fseek(in, -cur_block, SEEK_CUR);
file_left -= cur_block;
// actual reversing
for(int i = 0; i < cur_block / 2; ++i) {
swap(buf, i, cur_block - 1 - i);
}
// make sure we write a full block
do {
ssize_t written = fwrite(buf + cur_block - buf_filled, sizeof(char), buf_filled, out);
buf_filled -= written;
if(written < 0) {
return 1;
}
} while(buf_filled > 0);
}
return 0;
}
int main(int argc, char* args[]) {
FILE *in, *out;
if(argc > 1) {
in = fopen(args[1], "r");
if(in == NULL) {
fprintf(stderr, "unable to open input file!\n");
return 3;
}
} else {
fprintf(stderr, "give me an input file!\n");
return 2;
}
if(argc > 2) {
out = fopen(args[2], "w");
if(out == NULL) {
fprintf(stderr, "unable to open output file!\n");
return 3;
}
} else {
out = stdout;
}
return reverse(in, out);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment