Thus, I write a tool to convert any binary file to hex-printable text file and then convert back.
There're some differences between unix and windows while programming the tool. I encountered two differences.
First one. I decide to use ifstream and ofstream STL classes to achieve this. In unix, even though I do not specify "ios:binary" while creating ifstream/ofstream object, it works well. But in windows, I have to specify "ios:binary", otherwise, problems encountered,
e.g. ifstream returns EOF(End of File) prematurely, output file is larger than expected(because "\n" is translated to "\r\n"), etc.
Second one, a minor one. There's strcasecmp function in unix, but there's not in windows. The counterpart of strcasecmp in windows is stricmp.
Notes. In unix, "split" can be used to divide a large file to small ones, "xxd" can be used to dump a binary file to hex-printable characters, "cat" can be used to do the reverse thing. In windows, "type" is the counterpart of "cat".
#include <stdio.h> #include <ctype.h> #include <string.h> #include <assert.h> #include <iosfwd> #include <iostream> #include <fstream> #include <cstdlib> using namespace std; char hex2num(char c); short hexNumFromChar(char* c2); void error_exit(char* err) ; void usage_exit(char**) ; char dic[]="0123456789ABCDEF"; int main(int argc, char* argv[]){ if(argc!=4) { usage_exit(argv); } bool isEncode = false; if (stricmp(argv[1],"encode")==0){ isEncode = true; } else if(stricmp(argv[1],"decode")==0) { isEncode = false; } else { usage_exit(argv); } ifstream ifile(argv[2],ios::binary); ofstream ofile(argv[3],ios::binary); if(!ifile || !ofile){ error_exit("check infile and outfile"); } char c; short s; char hi,lo; char buf[2]; //int total=0; if(isEncode) { while(ifile.read(&c,1)){ //cout << ++total << endl; hi = (((unsigned char)c & 0xf0) >> 4); lo = ((unsigned char)c & 0x0f); ofile.put(dic[hi]); ofile.put(dic[lo]); } } else { while(true) { if(!ifile.read(&c,1)) break; buf[0]=c; if(!ifile.read(&c,1)) error_exit("the file have odd number of chars"); buf[1]=c; s=hexNumFromChar(buf); //c=((buf[0]<<4) | (buf[1]&0xf)); ofile.put((char)s); } } ofile.flush(); ifile.close(); ofile.close(); return 0; } void error_exit(char* err) { cerr<<err<<endl; exit(1); } void usage_exit(char** argv) { cout << "Usage:" << argv[0] << " <encode/decode> <infile> <outfile>" << endl; exit(2); } short hexNumFromChar(char* c2){ char n1,n2; n1=hex2num(c2[0]); n2=hex2num(c2[1]); return n1*16+n2; } char hex2num(char c){ if (isdigit(c)) return c-'0'; if (isalpha(c)) { if(islower(c)) c=toupper(c); return 10+c-'A'; } assert(0); return -1; }