对一个文件的所有行进行重新排列
2016-04-24 21:27 双头蛇 阅读(252) 评论(0) 编辑 收藏 举报#include <iostream> #include <time.h> using namespace std; //#define DEBUG //#define TOO_MANY_RECORDS #define FCLOSE(fp) do \ { \ if(NULL!=(fp)) \ { \ fclose((fp)); \ fp=NULL; \ } \ } while (0); enum ERRORCODE { ERR_OK, ERR_BAD_PARA, ERR_FILE_OPEN_ERR, ERR_LINE_BUFF_TWO_LONG, #ifdef TOO_MANY_RECORDS ERR_TOO_MANY_RECORDS, #endif ERR_MAX }; const int RECORD_COUNT = 10000; //THIS CAN BE CHANGE IF YOU NEED!!! const int MAX_CHARACHTR = 260; //the max number of characters of absolute path name is 259 characters. const int SIZE = 2*MAX_CHARACHTR; //because of above, I can assume that each line must be less than 520bytes. char buf[RECORD_COUNT*SIZE] = {0}; //assume that the file has 10000 records,and each record has 520 bytes. char line[SIZE] = {0}; char errmsg[ERR_MAX][128] = {0}; int rndbuf[RECORD_COUNT] = {0}; void initial_error_msg() { sprintf(errmsg[ERR_OK], "no error."); sprintf(errmsg[ERR_BAD_PARA], "parameter is wrong."); sprintf(errmsg[ERR_FILE_OPEN_ERR], "can't open file for read or write."); sprintf(errmsg[ERR_LINE_BUFF_TWO_LONG], "file has a line that more than %d bytes.",SIZE); #ifdef TOO_MANY_RECORDS sprintf(errmsg[ERR_TOO_MANY_RECORDS], "file has too many records(more than %d).",RECORD_COUNT); #endif } void die(enum ERRORCODE err) { if(err < ERR_MAX) { printf("%s",errmsg[err]); exit(err); } }; void main(int argc, const char *argv[]) { char *p,*q; int i,j; int records; FILE *fp; #ifndef DEBUG if(argc!=2) { printf("use %s -h to find help.",argv[0]); exit(ERR_BAD_PARA); } #endif initial_error_msg(); #ifndef DEBUG if( (((char *)argv[1])[0]=='-') && (((char *)argv[1])[1]=='h') && (((char *)argv[1])[2]=='\0') ) { #ifdef TOO_MANY_RECORDS printf("USAGE:\t%s -h:look up this help.\n\t%s filename:rearrange the file.\n\tNOTE:THE RETURN VALUE HAS THE FOLLOWING MEANINGS\n\t%d:%s\n\t%d:%s\n\t%d:%s\n\t%d:%s\n\t%d:%s",\ argv[0],argv[0], ERR_OK,errmsg[ERR_OK], ERR_BAD_PARA,errmsg[ERR_BAD_PARA], ERR_FILE_OPEN_ERR,errmsg[ERR_FILE_OPEN_ERR], ERR_LINE_BUFF_TWO_LONG,errmsg[ERR_LINE_BUFF_TWO_LONG], ERR_TOO_MANY_RECORDS,errmsg[ERR_TOO_MANY_RECORDS] ); #else printf("USAGE:\t%s -h:look up this help.\n\t%s filename:rearrange the file.\n\tNOTE:THE RETURN VALUE HAS THE FOLLOWING MEANINGS\n\t%d:%s\n\t%d:%s\n\t%d:%s\n\t%d:%s",\ argv[0],argv[0], ERR_OK,errmsg[ERR_OK], ERR_BAD_PARA,errmsg[ERR_BAD_PARA], ERR_FILE_OPEN_ERR,errmsg[ERR_FILE_OPEN_ERR], ERR_LINE_BUFF_TWO_LONG,errmsg[ERR_LINE_BUFF_TWO_LONG] ); #endif exit(ERR_OK); } #endif #ifndef DEBUG fp = fopen(argv[1], "rb"); #else fp = fopen("list.tmp","rb"); #endif if(fp==NULL) { FCLOSE(fp); die(ERR_FILE_OPEN_ERR); } i = 0; p = buf+i*SIZE; /*Read file lines to buf*/ while((q=fgets(p, SIZE, fp))!=NULL) { int len = strlen(p); if(len >= SIZE - 1) { //line buff is too long. FCLOSE(fp); die(ERR_LINE_BUFF_TWO_LONG); } else if( (p[0] == 0x0d)||(p[0] == 0x0a) ) { //empty line. continue; } i++; if(i>=RECORD_COUNT) { //too many records. #ifdef TOO_MANY_RECORDS while((q=fgets(line, SIZE, fp))!=NULL) { if( (line[0]!=0x0d)&&(line[0]!=0x0a) ) { FCLOSE(fp); die(ERR_TOO_MANY_RECORDS); } } #endif break; } p = buf+i*SIZE; }/*END OF READ*/ records = j = i;//record counts for(i = 0; i < records; i++) { rndbuf[i] = i; } srand(time(0)); while(j > 1) { register int tmp; register int rnd = rand()%j; tmp = rndbuf[rnd]; rndbuf[rnd] = rndbuf[j-1]; rndbuf[j-1] = tmp; j--; } FCLOSE(fp); #ifndef DEBUG fp = fopen(argv[1], "wb"); #else fp = fopen("list.tmp","wb"); #endif if(fp==NULL) { FCLOSE(fp); die(ERR_FILE_OPEN_ERR); } for(i=0; i < records; i++) { fputs(&buf[rndbuf[i]*SIZE],fp); } FCLOSE(fp); }