c-programing 질문.
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char str1[100]; char str2[10]; char buffer_test[100]; fputs("Please input any sentence: " , stdout); fgets(str1 , sizeof(str1) , stdin); printf("\n"); strncpy(str2 , str1 , sizeof(str2)-1 ); // copy str2[sizeof(str2)-1] = '\0'; // This is the last index of str2. fputs("The sentence that copied: " , stdout); printf("%s" , str2); system("PAUSE"); return 0; }
=> 입력받은 문자열을 복사해서 다시 출력해주는 간단한 프로그램입니다. 프로그램상 문제점은 없습니다.
하지만 "str2[sizeof(str2)-1] = '\0' 구문을 주석처리 하면 어떤 결과가 초래 될것인가?" 라는 질문에 답하기 위해[책에서 해보라고해서 한번 해 본것 입니다..(열혈강의 c 프로그래밍)]
해당 구문을 주석 처리하고 컴파일한후 프로그램을 실행하면서 '의아한 부분' 을 발견했습니다. 바로 printf("%s" , str2); 구문에 의해서 출력되어 지는 부분입니다.
▼[str2[sizeof(str2)-1] = '\0' 구문 주석처리 했다는 가정 하에 프로그램 실행 예]▼ (출력 결과 그대로 입니다)
Please input any sentence: hello world
The sentence that copied: hello woruhello world
계속하려면 아무 키나 누르십시오.......
=> str2같은 경우 배열의 크기가 10이라서 hello wor(쓰레기값) 이라는 결과가 출력 될것이라고 예측 했었습니다. 하지만 출력결과는 완전 딴판이었 더군요..
문자열(str2의 배열) 끝에 null문자가 없는대 모양새는 이상하지만 문자열을 출력했다는 것과, str2보다 크기가 큰 문자열이 출력되었다는 점..이 2가지를 도대체 어떻게 설명을 해야 할지 모르겠습니다..
그 쓰레기값이 우연히 'u'의
그 쓰레기값이 우연히 'u'의 코드값이었나보죠.
그리고 printf 는 그저 문자열의 시작 주소를 인자로 받을 뿐이고(str2는 배열의 이름이고
배열의 이름이 단독으로 수식으로 쓰였기 때문에 첫 원소의 주소로 해석됩니다)
%s 포맷을 처리할 때는 문자열의 시작주소부터 시작해서 널 캐릭터가 존재할 때까지 쭉
따라가면서 그 내용을 출력할 뿐이고, str2 배열의 크기가 몇인지는 알 수도 없고 알려고 하지도 않습니다.
아마도 main 함수의 지역변수들이 메모리에 할당될 때
arr2가 할당된 10바이트 바로 뒤에 arr1이 할당된 걸로 보이고요.
결과적으로 printf 는
- arr2 의 시작주소를 받아서
- 거기서부터 처음 복사된 "hello wor" 9글자와,
- 그 다음 바이트에 있던 쓰레기값 'u' 와,
- 그 다음 바이트에 있던 arr1의 첫 글자 h와
- 그 뒤를 이어 나머지 전부까지 출력하고
- "world"와 아마 그 뒤에 있었을 '\n'까지 출력한 후
- 그 뒤에 있는 '\0'을 보고 출력을 멈추었겠죠.
좋은 하루 되세요!
늦은 대댓글, 죄송합니다.
덕분에 몰랐던 부분에 대해서 명쾌히 알고 갑니다! 감사합니다 :)
댓글 달기