2017-11-23 2 views
0

나는 이것이 질문의 칠면조가 아니길 바란다. EOF를 탐지하기위한 조건부가 작동하지 않는 것 같습니다. 코드는 EOF를 통해 계속 진행되며 명령문 내에서 처리됩니다. 텍스트를 다시 만들면 적절하게 나타납니다. 그러나 쓰레기 코드가있는 전체 bmp는 인코딩되지 않은 텍스트 플래그의 끝을 알려주며 인쇄합니다. 다음 조건문에 printf 문을 두었습니다. 그러나 결코 인쇄 할 수는 없습니다. 나는 그것이 문제가 무엇인지, 나 앞에서 옳은지, 아니면 좀 더 불길한 것을 볼 수 없다. 언제나처럼 고마워!EOF가 검출되지 않는다

/******************************************************************************* 
* This code is to take a text document and using steganography techniques, hide 
* the text within a bmp. It will take each character of the text, parse it into 
* four 2 bit pieces and inject those bits into the two least significant bits 
* of each pixel color (BGR) byte as well as the line padding. 
******************************************************************************/ 
#include <stdio.h> 

/******************************************************************************* 
* getIntFromArray (borrowed from class notes). Takes unsigned character array 
* and assembles/returns an int value using bit shifting with OR. 
******************************************************************************/ 
int getIntFromArray(unsigned char bytes[]) 
{ 
    int n = 
      bytes[0] | 
      bytes[1] << 8 | 
      bytes[2] << 16 | 
      bytes[3] << 24; 
    return n; 
} 

/******************************************************************************* 
* bitWise. Take unsigned char pointer and character, parses the character 
* using bitwise manipulation and injects 2 bits into the 2 least significant 
* bits of each pixel color byte as well as padding. 
******************************************************************************/ 
void bitWise(unsigned char* bytes, char character) 
{ 
    int i; 
    char tmpChar; 
    for(i = 0; i < 4; ++i) 
    { 
    tmpChar = character; 
    tmpChar &= 3; 
    bytes[i] &= 252; 
    bytes[i] |= tmpChar; 
    character = character >> 2; 
    } 
} 

int flag = 0; 

int main(int argc, char **argv) 
{ 
    char *infilename = argv[1]; 
    char *outfilename = argv[2]; 

    unsigned char header[54]; 

    FILE *in = fopen(infilename, "rb");/*Command line input.*/ 
    FILE *out = fopen(outfilename, "wb");/*Command line input.*/ 

    int pixelWidth; 
    int pixelHeight; 
    int i; 
    int j; 

    fread(header, 1, 54, in);/* read header into array */ 

    pixelWidth = getIntFromArray(&header[18]); 
    pixelHeight = getIntFromArray(&header[22]); 

    fwrite(header, 1, sizeof(header), out);/* write header to output file */ 

    for(i = 0; i < pixelHeight; ++i)/*Loop to read pixel data from bmp.*/ 
    { 
    for(j = 0; j < pixelWidth; ++j) 
    { 
     unsigned char bytes[4]; 
     unsigned char character = 0; 

     fread(&bytes, 1, 4, in);/*Reads sequentially pixel and padding bytes.*/ 
     if(flag == 0)/*Breakout flag, initially set to 0.*/ 
     { 
     character = getchar();/*Takes in characters from stdin.*/ 
     if(character != EOF)/*Breakout if EOF.*/ 
     { 
      bitWise(bytes, character); 
     } 
     else 
     { 
      bitWise(bytes, 0);/*Sets end of hidden text with 4 bytes LSB to 0.*/ 
      flag = 1; 
     } 
     } 
     fwrite(&bytes, 1, 4, out); 
    } 
    } 
    fclose(in); 
    fclose(out); 
    return 0; 
} 
+0

아마도'fread'의 반환 값을 확인하는 것이 도움이 될 것입니다. –

답변

2

당신은 unsigned intsigned int를 할당한다. 그 결과는 당신이 기대하는 바가 아닐 것입니다. 모든 비트가 1으로 설정된 값이됩니다. (EOF은 값이 -1이므로 서명 됨).

길게만 짧으면 int이어야합니다. 단순한 int character이이 용도로 사용됩니다.

또 다른 것 getchar()int을 반환합니다.

  • fread 반환 값은 확인해야합니다 : - int getchar(void);

    할 일이 몇 가지 다른 일이 있습니다.

    size_t fread(void * restrict ptr,size_t size, size_t nmemb,FILE * restrict stream);

fread 기능

는 읽기 오류 또는 파일의 마지막 가 발생하면보다 nmemb을 할 수있는 요소의 수를 성공적으로 읽기를 반환합니다. size 또는 nmemb가 제로의 경우, fread 반환 배열의 내용과 stream 의 상태를 제로와 는

  • 또 다른 한가지는 fopen()의 반환 값을 확인하는 것입니다 변경되지 않습니다. 실패한 경우 반환 값은 NULL입니다.
+0

감사하고 수정 된 부호없는 정수. 아직도 문제가 있습니다. –

+0

(EOF는 -1이므로 서명 됨)이 중요했습니다! 나는 서명되지 않은 char을 제거하고 int에서 cast와 char만을 사용했다. –

+2

@MichaelServilla :'getchar()'의 결과를'char','unsigned char' 또는'signed char'가 아닌'int'에 저장해야합니다. 왜냐하면'getchar()'는 256 문자 값 (8 비트 문자라고 가정)과 EOF 값을 반환 할 수 있기 때문입니다. 문자 유형에 값을 저장하면 정보를 버리게됩니다. 이는 위험합니다. EOF를 결코 감지하지 못하거나 너무 빨리 EOF를 감지 할 수 있습니다. –

1

심각한 두 그러나 저를 이끌어 여기 일반적인 문제는 평판이 책은 초기에 이러한 문제를 다룰 것입니다, 당신은 평판 좋은 책을 읽고하지 않는, 또는 당신이 그것을 심각한 문제가 발생하는 믿을가있다 장.

아마도 현재 사용하고있는 것이 무엇이든간에 당신을 위해 일하지 않기 때문에 다른 옵션을 살펴봐야 할 것입니다. 당신은 시행 착오로 어려움을 겪고있는이 모든 시간에 당신의 책을 읽을 수 있었을 것이고, 당신의 책은 보통 일반적인 이슈 지나서 당신을 멋지게 인도해야했습니다.

최종 줄은 입니다. 반환 값을 고려해야합니다.

  • 반환 값을 확인하기 전에 변환하지 마십시오.unsigned char character; character = getchar();에서 EOF에 대해 확인하기 전에 getchar manual의 내용이 int이고 unsigned char 인 것으로 변환됩니다. 해당 변환 은 데이터가 손실 될 수 있습니다. 잃어버린 데이터가 궁금하십니까?

당신이 K & R2E 또는 매뉴얼을 이해하는 데 어려움을 겪고 있다면, 당신은 당신이 아니라 추측에 의존하는 코드를 작성하는 혼란, 이동하기보다, 이해하지 못하는 것을에 대한 질문을 작성해야합니다. 모든 추측 (54)을 통과 등 C.

또한 fread의 반환 값을 확인해야하고, 나는 size 매개 변수를 볼 것으로 예상 것 같은 언어의 위험과 count 매개 변수는 경우에 1을 통과시켰다. fread쉰세 바이트 (또는 쉰두, 또는 쉰한) 것처럼 입력의 끝이 아니라 치료보다의를 읽을 때 그런 식으로, 당신이 경우 치료를 할 수 예기치 않게 짧은 입력으로 예상 크기이긴하지만. getchar 설명서와 마찬가지로 freadthe fread manual에서 모두 확인할 수 있습니다.

오, 그리고 요즘에는 "Youtube videos"응답이 많습니다. 유튜브 (Youtube)는 평판이 좋은 책을 대체하지 못합니다. 누구든지 거기에 뛰어 들고 "그냥 날개 달기"만하면 시계에서 보는 비디오에 자신이 추측하는 것과 똑같이 결함이 생길 것입니다. 반면 평판이 좋은 책은 수천 시간을 계획, 동료 검토, 테스트 (학생들에게 가르치기위한 수업이있는 교수가 작성하기 때문에), 리팩토링 (테스트를 바탕으로 발생하는 "딸꾹질"에 더 잘 대처 함).

선택의 여지가 분명해야하며 증명은 푸딩을 먹는 중입니다. "youtube"또는 "try it and see"방법을 시도했다면, 그들은 당신을 위해 일하지 않을 것입니다; 지금 당신 앞에 보이는 것은 그 결과입니다. 다른 것을 시도하십시오. 행운을 빕니다!

관련 문제