2008-11-06 5 views
11

사용자가 하나씩 입력 할 문자를 저장하는 데 사용하는 문자 배열 버퍼가 있습니다. 작품 아래에 내 코드하지만 내가 알아낼 수있는 몇 가지 결함이있다 : 나는 버퍼에 무엇을 볼 수있는의 printf를 실행할 때끝에 가비지 문자가있는 문자열 배열

  1. , 그것은 채워 않습니다를하지만 난 마지막에 가비지 문자를 얻을 수
  2. 을 char 버퍼 [8]로 선언되었지만 8 문자로 멈추지 않습니다.

누군가 제발 내가 무슨 일이 일어나고 있는지 그리고 어떻게 해결할 수 있을지 설명해 주실 수 있습니까? 감사.

char Buffer[8]; //holds the byte stream 
int i=0; 

if (/* user input event has occurred */) 
{ 
     Buffer[i] = charInput; 
     i++; 

     // Display a response to input 
     printf("Buffer is %s!\n", Buffer); 

} 

출력 :

 
tagBuffer is 1┬┬w! 
tagBuffer is 12┬w! 
tagBuffer is 123w! 
tagBuffer is 1234! 
tagBuffer is 12345! 
tagBuffer is 123456=! 
tagBuffer is 1234567! 
tagBuffer is 12345678!

tagBuffer는 123456789입니다!

답변

26

\ 0 문자로 문자열을 끝내야합니다. 이것이 제로 종료 문자열이라고하는 이유입니다.

\ 0을 보유하려면 1 개의 여분의 char을 할당하는 것이 좋습니다.

+0

굉장합니다. 감사. 단 하나의 질문 : 버퍼 [8]의 요점은 무엇입니까? – Steve

+0

buffer [8]는 컴파일러에게 배열에 8 바이트의 메모리를 할당하도록 지시합니다. 문자열은 이보다 짧을 수 있지만 (예 : "buffer [4] = 0;"을 수행하여) 더 길 수는 없습니다. –

+1

버퍼 [8]은 7 개의 문자와 하나의 터미네이터를위한 버퍼입니다 ;-). –

8

printf() 함수에 전달하는 유일한 것은 문자열의 첫 번째 문자를 가리키는 포인터입니다. printf()는 배열의 크기를 알 수 없습니다. (포인터가 메모리 주소 일 뿐이므로 실제 배열인지 여부조차 알지 못합니다.)

printf() 및 모든 표준 C 문자열 함수는 문자열 끝에 0이 있다고 가정합니다. 의 printf() 그것이 0

따라서이 같은 뭔가 코드를 변경해야합니다 돌 때까지, 당신은 함수에 전달하는 문자에서 시작, 메모리에 인쇄 문자를 유지합니다 예 :

char Buffer[9]; //holds the byte stream 
int i=0; 

if(//user input event has occured) 
{ 
     Buffer[i] = charInput; 
     i++; 

     Buffer[i] = 0; // You can also assign the char '\0' to it to get the same result. 

     // Display a response to input 
     printf("Buffer is %s!\n", Buffer); 

} 
0

C 또는 C++로 프로그래밍하는 경우 다음을 기억해야합니다. 1) 문자열은 \ 0 문자로 끝납니다. 2) C는 문자열에서 경계 검사를하지 않으며 문자 배열입니다.

-1

stringstream을 사용해 보길 원할 수도 있습니다.

+1

문자열 스트림이 C와 관련이 없습니다. – quinmars

3

제로 터미네이션에 대한 이전 의견 외에도 자신의 버퍼 오버 플로우에 대한 책임도 받아 들여야합니다. 코드가 멈추지 않기 때문에 8 자로 멈추지 않습니다! 즉

#define DATA_LENGTH 8 
#define BUFFER_LENGTH (DATA_LENGTH + 1) 

char Buffer[BUFFER_LENGTH]; //holds the byte stream 
int charPos=0; //index to next character position to fill 

while (charPos <= DATA_LENGTH ) { //user input event has occured 
    Buffer[i] = charInput; 

    Buffer[i+1] = '\0'; 

    // Display a response to input 
    printf("Buffer is %s!\n", Buffer); 

    i++; 

} 

만들 최대 길이에 도달하면 데이터 수신을 중단해야 관계없이 환경이 당신을 밀어하려고 무엇을 : 당신은 (제레미의 제안 위에 돼지 - 뒷면) 다음과 같은 뭔가가 필요 .

+0

sizeof (버퍼)를 사용하십시오! –

+0

@Jonathan : DATA_LENGTH가 기본 앱 도메인 개념이고 Buffer의 크기가 종속 값이었고 그 반대의 경우라고 가정했습니다. Buffer와 아무 관련이없는 DATA_LENGTH의 다른 용도가있을 수 있으므로이를 언급해서는 안됩니다. –

+0

@ joel.neely 위의 코드가 올바르지 않더라도 (명령문 주석 위치가 틀림) 다음 문자를 '\ 0'으로 설정하면 upvote가 필요합니다. 해결책입니다. "Buffer [i] = charInput; Buffer [i + 1] = '\ 0'; i ++;" 명확하게 말하면, 구현이 올바르지는 않지만 같은 줄에 2 개의 변수를 설정 했으므로 디버그하기가 더 어려울뿐입니다 (스타일에 대한 질문입니다). –

0

그것은 아무도 이러한 가능성을 언급하지 않았다 것은 이상 :

char Buffer[8]; //holds the byte stream 
int i = 0; 

while (i < sizeof(Buffer) && (charInput = get_the_users_character()) != EOF) 
{ 
    Buffer[i] = charInput; 
    i++; 

    // Display a response to input 
    printf("Buffer is %.*s!\n", i, Buffer); 
} 

의 printf() 형식 문자열이 표기가 표시 될 문자열의 최대 길이를 지정하고,하지만 (널 (null) 종료를 필요로하지 않습니다 널 종료는 궁극적으로 최선의 방법입니다 - 최소한이 루프를 빠져 나가면).

while 루프는 간단한 if보다 더 그럴듯이며,이 버전은 버퍼의 끝을 오버 플로우하지 않도록합니다 (그러나 당신이이 NUL '\0' 후행에 대한 충분한 공간을 남겨 보장하지 않습니다. 당신이 것을 처리하는 경우 루프 후 NUL을 추가 한 후 sizeof(Buffer) - 1를 사용합니다.

0

Buffer 때문에 초기화되지, 모든 9 쓰레기 값으로 시작합니다. 을 관찰 출력, 2, 3, 4, 5, 6, 7, 8에서와 2 즉각적인 다음 메모리 위치 (배열 외부) 요소는 분명히 'T', 'T', 'W',입니다. 210, '\0', '=', '\0', '\0', '\0'.

문자열은 NULL 문자가 나타날 때까지 모든 문자를 사용합니다. 그래서 모든 반복에서 배열 요소가 하나씩 할당되므로 버퍼가 가비지 NULL이있는 부분까지 인쇄됩니다.

즉, 문자 배열이 '\0'으로 끝나지 않으면 문자열의 동작이 정의되지 않은 것입니다. 버퍼의 끝에 '\0'에 대한 추가 공간을 확보하면이 문제를 피할 수 있습니다.