2016-10-29 2 views
1
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define BS 12 

void reverse(char * buffer, int size) 
{ 
    char tmp; 
    int i; 
    for(i = 0; i < size/2; i++) 
    { 
    tmp = (char)buffer[i]; 
    buffer[i] = buffer[size - i - 1]; 
    buffer[size - i - 1] = tmp; 
    } 
} 

int compare_bin(char * buffer, char * buffer2, int size) 
{ 
    // because strncmp is only for string without \x00, so there must be a customized compare function 
    int i; 
    for(i = 0; i < size; i++) 
    { 
    if(buffer[i] != buffer2[i]) 
     return 0; 
    } 
    return 1; 
} 

int main (const int argc, const char** argv) 
{ 
    if(argc != 3) 
    exit(-1); 

    int equal = 1; 
    char * buffer = malloc(BS), * buffer2 = malloc(BS); 
    FILE * f1, * f2; 
    f1 = fopen(argv[1], "r"); 
    f2 = fopen(argv[2], "r"); 

    fseek(f1, 0, SEEK_END); 
    fseek(f2, 0, SEEK_END); 

    long i = ftell(f1), j = ftell(f2); 
    if(i != j) 
    { 
    equal = 0; 
    goto endp; 
    } 

    fseek(f2, 0, SEEK_SET); 

    int need = 0; 
    int count; 
    int f2_pos = 0; 

    do 
    { 
    i = i - BS; 
    if(i < 0) 
    { 
     need = BS - abs((int)i); 
     i = 0; 
    } 
    else 
     need = BS; 

    fseek(f1, i, SEEK_SET); 
    count = fread(buffer, need, 1, f1); 

    reverse(buffer, count * need); 
    // fwrite(buffer, count * need, 1, f2); 
    fread(buffer2, need * need, 1, f2); 

    // printf("compare...\n"); 
    // for(int i = 0; i < need * count; i++) 
    // { 
    // printf("%02hhX", buffer[i]); 
    // } 
    // printf("\n"); 
    // for (int i = 0; i < need * count; i++) 
    // { 
    // printf("%02hhX", buffer2[i]); 
    // } 
    // printf("\n"); 


    if(compare_bin(buffer, buffer2, need * count) == 0) 
    { 
     equal = 0; 
     break; 
    } 

    f2_pos += need * count; 
    fseek(f2, f2_pos, SEEK_SET); 

    if(i == 0) 
     break; 
    }while(i > 0); 

    fclose(f1); 
    fclose(f2); 
    free(buffer); 
    free(buffer2); 

    endp: 
    if(equal) 
    return 0; 
    else 
    { 
    printf("2 files not equal is reversed order\n"); 
    return 1; 
    } 

    return 0; 
} 

그래서 파일 내용을 역순으로 비교하는 프로그램을 작성합니다. 이미 이진 파일에서 \x00을 고려했으며 strncmp은 사용하지 않았습니다. 그러나 여전히 결함이 있습니다. 이 프로그램을 테스트 할 테스트 서버가 있습니다. 하지만 나는 그것에 접근 할 수 없다. 이 프로그램은 항상 해당 서버에서 실패합니다. 따라서 실패하게 만들려면 특별한 경우가 있어야합니다. 어떤 생각?파일을 역순으로 비교하면서 특별한 경우를 찾습니다.

다른 방법이 있습니다. 예를 들어 MD5를 계산합니다. 하지만이 문제를 해결하고 싶습니다. 데이터를 읽는 첫 번째 반복에 대한

+0

바이너리 파일을 다루는 경우''r "'모드가 아니라" "rb"'모드를 사용하여 파일을 엽니 다. –

+0

잭, 당신은 지금이 질문의 변이를 몇 번이나 물었습니다. 이전에'size'와'count' 논쟁이 다른 방향으로 진행되었다는 것을 이전에 알고 있었기 때문에 더 멀리 가기 전에'fread'와 비슷한'fwrite'에 대한 man 페이지를 읽으라고 제안 할 수 있을까요? 여러 게시물을 올린 후에도 "순진한 타이핑 오류가 있습니까?" –

+0

@WeatherVane 죄송합니다. 나는 하루 종일 프로그래밍을 해왔다. 나는 아주 피곤하고 순진한 실수를 저질렀습니다. 솔직히, 그것은 입력 오류입니다. 그 사람이 대답을 취소하면이 게시물을 기꺼이 삭제할 수 있습니다. –

답변

1

당신은 문제는이 경우 needbuffer2에 할당 된 메모리의 크기 12, 점이다

fread(buffer2, need * need, 1, f2); 

을 가지고,하지만 당신은 12 * 12을 읽을 요청 바이트.

두 번째 파일이 충분히 큰 경우 메모리 범위를 벗어나 의 정의되지 않은 동작이됩니다. 파일이 이 아니고이 아니면 충분히 읽을 수 없습니다.

두 중간 인수의 순서는 fread입니다. 순서를 변경했을 경우, 파일이 need * need보다 큰지, 양쪽 모두가 버퍼의 경계 밖으로 써 낼 것입니다. 실제로 count 바이트 크기의 객체를 읽어야합니다 (두 번째 인수는 1이어야하고 세 번째는 count이어야합니다. 물론 첫 번째 호출에서도 순서를 변경해야 함). 한마디로

, 당신이 fread 호출

count = fread(buffer, 1, BS, f1); 
fread(buffer2, 1, count, f2); 

PS해야한다. 오류 검사를 잊지 마십시오.

+0

oops. 그'need * needs'는 필자의 타이핑 오류입니다. –

관련 문제