Created
October 21, 2012 13:35
-
-
Save thammi/3926956 to your computer and use it in GitHub Desktop.
Reverse a file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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