programing

문자 배열의 null 종료

oldcodes 2023. 6. 8. 22:32
반응형

문자 배열의 null 종료

다음과 같은 경우를 고려합니다.

#include<stdio.h>
int main()
{
    char A[5];
    scanf("%s",A);
    printf("%s",A);
}

내 질문은 만약 char.A[5]두 개의 문자만 포함합니다.을 "ab" 말라고하면이,말하면고,A[0]='a',A[1]='b'그리고.A[2]='\0'이 "라고 말한다면, "abcde"입니까?'\0'그런 경우에는할 것이다A[5]어있다를 '\0'만약 그렇다면, 왜? sizeof(A)항상 5를 답으로 반환합니다.그러면 어레이가 꽉 찼을 때 다음을 위해 예약된 추가 바이트가 있습니까?'\0' 쪽인가요?sizeof()계산이 안 되나요?

네 개 이상의 문자를 입력하면 추가 문자와 null 종결자가 배열 끝 바깥에 쓰여 배열에 속하지 않는 메모리를 덮어씁니다.버퍼 오버플로입니다.

C는 당신이 소유하지 않은 메모리를 분해하는 것을 막지 않습니다.로 인해 정의되지 않은 동작이 발생합니다.프로그램이 충돌하거나 다른 변수를 조용히 무시하고 혼란스러운 동작을 유발하거나 해롭지 않을 수 있습니다.프로그램이 안정적으로 작동하거나 중단된다는 보장은 없습니다.당신은 그것이 즉시 충돌할 것이라고 기대할 수도 없습니다.

이것은 왜 그런지에 대한 훌륭한 예입니다.scanf("%s")위험하므로 절대 사용해서는 안 됩니다.어레이의 크기를 알 수 없기 때문에 안전하게 사용할 수 있는 방법이 없습니다.대신 스캔을 피하고 fgets()와 같은 더 안전한 것을 사용합니다.

fgets()는 스트림에서 크기보다 작은 문자를 최대 1개 읽어 들이고 s가 가리키는 버퍼에 저장합니다.EOF 또는 새 줄 이후에 판독이 중지됩니다.새 줄이 읽히면 버퍼에 저장됩니다.종료 null 바이트('\0')는 버퍼의 마지막 문자 뒤에 저장됩니다.

예:

if (fgets(A, sizeof A, stdin) == NULL) {
    /* error reading input */
}

짜증나게도 fgets()는 배열 끝에 뒤에 오는 줄 문자('\n')를 남깁니다.코드를 사용하여 제거해야 할 수도 있습니다.

size_t length = strlen(A);
if (A[length - 1] == '\n') {
    A[length - 1] = '\0';
}

한 ( 부서진) 윽. 단하한 (순지부서진만하)부진▁()scanf("%s")7월 를 잘 못합니다.이것이 오늘의 두 번째 교훈입니다. C는 I/O와 문자열 처리에 능숙하지 않습니다.그것은 할 수 있고, 안전하게 할 수 있지만, C는 내내 발로 차고 소리를 지를 것입니다.

이미 지적했듯이 N 문자를 올바르게 저장하려면 길이 N + 1의 배열을 정의/할당해야 합니다.scanf에서 읽는 문자 수를 제한할 수 있습니다.예를 들어 다음과 같습니다.

scanf("%4s", A);

stdin에서 최대 4개의 문자를 읽기 위해.

문자 배열은 메모리 블록에 대한 포인터일 뿐입니다.컴파일러에게 문자에 대해 5바이트를 예약하라고 하면 예약이 됩니다.5바이트 이상을 삽입하려고 하면 예약한 5바이트가 지난 메모리를 덮어씁니다.

그것이 c가 심각한 보안 구현을 할 수 있는 이유입니다.당신은 오직 4자 + 0을 쓸 것이라는 것을 알아야 합니다.C는 프로그램이 중단될 때까지 메모리를 덮어쓸 수 있게 해줍니다.

charfoo[5]를 문자열로 생각하지 마십시오.5바이트를 넣는 자리라고 생각하시면 됩니다.null 없이 5개의 문자를 저장할 수 있지만 메모리(다른 CharArray, foo, 5)를 수행하고 strcpy를 사용하지 않아야 합니다.또한 다른 CharArray에는 5바이트를 저장할 수 있는 충분한 공간이 있습니다.

당신은 정의되지 않은 행동을 하게 될 것입니다.

대로 말하신 의것크는기의 .A항상 5일 것입니다, 그래서 만약 당신이 5개 이상을 읽는다면.chars,scanf수정해서는 안 되는 메모리에 쓰려고 할 것입니다.

한예문공간/된 공간.\0기호.

4를초문자열원은됩니인다이는과길하가됩▁cause▁any다니▁greater원이인▁will▁string자문▁charact가 발생합니다.scanf배열의 범위를 벗어나 쓰기.결과 동작이 정의되지 않았으며, 운이 좋으면 프로그램이 중단됩니다.

왜 그런지 궁금하다면,scanf 긴 을 멈추지 않습니다.A할 수 있는 방법이 없기 때문입니다.scanf을 알다sizeof(A)는 5입니다. C 함수에 매개 변수로 배열을 전달하면 배열이 배열의 첫 번째 요소를 가리키는 포인터로 붕괴됩니다.따라서 함수 내에서 배열의 크기를 쿼리할 수 없습니다.

배열에서 읽는 문자 수를 제한하려면 다음을 사용합니다.

scanf("%4s", A);

예약된 문자가 없으므로 전체 배열을 null로 종료할 수 없을 정도로 채우지 않도록 주의해야 합니다.char 함수는 null 종결자에 의존하며, 당신이 설명한 상황에 처한다면 당신은 그것들로부터 비참한 결과를 얻을 것입니다.

당신이 보게 될 많은 C 코드는 strncpy와 같은 함수의 'n' 도함수를 사용할 것입니다.해당 맨 페이지에서 다음을 읽을 수 있습니다.

strcpy() 및 strncpy() 함수는 s1을 반환합니다.stpcpy() 및 stpncpy() 함수는 s1의 종료 '\0' 문자로 포인터를 반환합니다.stpncpy()가 NUL 문자로 s1을 종료하지 않으면 대신 s1[n](유효한 메모리 위치를 참조할 필요는 없음)로 포인터를 반환합니다.

또한 strlen은 null 문자를 사용하여 문자 버퍼의 길이를 결정합니다.해당 문자가 누락된 경우 잘못된 결과를 얻을 수 있습니다.

배열의 종료에 null 문자가 사용됩니다.배열의 끝에 있으며 배열이 해당 지점에서 끝에 있음을 나타냅니다.배열은 컴파일러가 배열이 끝났다는 것을 쉽게 이해할 수 있도록 자동으로 마지막 문자를 null 문자로 만듭니다.

\0은 배열이 가득 차 있지 않으면 배열이 가득 차면 스스로 종료되는 종결 연산자이며 \0은 배열의 끝에서 읽을 문자열을 입력할 때 배열의 끝에 있게 됩니다.

언급URL : https://stackoverflow.com/questions/12019947/null-termination-of-char-array

반응형