char 배열 c 지우기


104

첫 번째 요소를 null로 설정하면 char 배열의 전체 내용이 지워질 것이라고 생각했습니다.

char my_custom_data[40] = "Hello!";
my_custom_data[0] = '\0';

그러나 이것은 첫 번째 요소 만 null로 설정합니다.

또는

my_custom_data[0] = 0; 

를 사용하는 대신 memset위의 두 가지 예가 모든 데이터를 지워야한다고 생각했습니다.


1
Jared, 왜 C ++ 태그를 설정 했습니까? 그는 "C"에 대해 이야기하고 C ++ 관련 태그를 추가하지 않았습니다.
Johannes Schaub-litb

1
이것은 그가 지정하지 않았지만 C ++의 문자 배열에도 똑같이 잘 적용됩니다.
Adam Hawes

4
C ++ 전용 솔루션을 제공하는 사람들에게 이미 본 것을 피하기 위해 C ++ 태그를 제거했습니다
Alnitak

답변:


113

어레이를 보는 방법에 따라 다릅니다. 배열을 일련의 문자로 보는 경우 데이터를 지우는 유일한 방법은 모든 항목을 터치하는 것입니다. memset이를 달성하는 가장 효과적인 방법 일 것입니다.

반면에 이것을 C / C ++ null로 끝나는 문자열로보기로 선택한 경우 첫 번째 바이트를 0으로 설정하면 문자열이 효과적으로 지워집니다.


4
대답의 핵심 단어는 '효과적으로'입니다. 첫 번째 요소 만 0으로 설정되고 나머지는 여전히 정의되지 않은 값을 갖지만 배열을 널로 종료 된 문자열로 취급하고 첫 번째 요소가 널인 경우 문자열은 비어있는 것으로 간주됩니다.
Arnold Spence

실제로 이것은 답변입니다.
Johannes Schaub-litb

@caparcode, 정확히. 그렇기 때문에 어레이가 어떻게 사용되는지 이해하는 것이 매우 중요합니다.
JaredPar

예, 그것이 제 첫 게시물에서 말 했어야하는 것입니다. 문자는 종료 된 문자열입니다. 그래서 이것들은 그 트릭을 할 것입니다. char [0] = '\ 0'; 또는 char [0] = 0. 확실하지 않지만 null로 끝나는 문자열을 사용하는 데 '\ 0'을 사용하는 것이 더 좋다고 들었습니다.
ant2009

@robUK, 네 맞습니다. 기술적으로 '\ 0'(ASCII)에 0과 동일하지만, 그것은 당신의 의도를 명확하게하기 때문에 당신은 '\ 0'를 사용한다
마크 테 스타

70

C의 배열은 메모리 위치 일 뿐이므로 실제로 my_custom_data[0] = '\0';할당은 첫 번째 요소를 0으로 설정하고 다른 요소는 그대로 둡니다.

배열의 모든 요소를 ​​지우려면 각 요소를 방문해야합니다. 그 이유 memset는 다음과 같습니다.

memset(&arr[0], 0, sizeof(arr));

이것은 일반적으로 이것을 처리하는 가장 빠른 방법입니다. C ++를 사용할 수 있다면 대신 std :: fill을 고려하십시오.

char *begin = &arr;
char *end = begin + sizeof(arr);
std::fill(begin, end, 0);

1
두 번째 버전은 다음과 같아야한다고 생각합니다. std :: fill (arr, arr + sizeof (arr) / sizeof (arr [0]), 0);
David Rodríguez-dribeas

설명 : int, long, double 또는 무엇을 가지고 있는지 나중에 문제가 발생할 수 있으므로 채우기와 함께 sizeof를 사용하지 마십시오.
Zan Lynx

나는 선호한다 : std :: fill (& arr [0], & arr [arr_len], 0);
Zan Lynx

Zan Lynx, 그것은 정의되지 않은 행동입니다. & arr [arr_len]을 할 수 없습니다. 하지만 std :: fill (arr, arr + sizeof arr, 0); 또는 길이가 std :: fill (arr, arr + arr_len, 0); 문자의 배열을 가정
요하네스 SCHAUB - litb

C에서만 유효합니다. 질문은 분명히 C를 대상으로하지만 (다른 사람이 C ++ 태그를 추가했지만 이유는 모르겠습니다) std :: fill은 C ++ 친 화성을 보여줍니다. :)
Johannes Schaub-litb

25

단일 요소를 설정하면 전체 배열이 지워지는 이유는 무엇입니까? 특히 C에서는 프로그래머가 명시 적으로 프로그래밍하지 않으면 거의 발생하지 않습니다. 첫 번째 요소를 0 (또는 임의의 값)으로 설정하면 정확히 수행 한 것입니다.

초기화 할 때 배열을 0으로 설정할 수 있습니다.

char mcd[40] = {0}; /* sets the whole array */

그렇지 않으면 memset이나 비슷한 것 외에 다른 기술을 모릅니다.


나는이 사용하는 컴파일러에 따라 달라집니다 것 같아요
cocoafan

1
@cocoafan : 아니요, 컴파일러에 의존하지 않습니다. 언어 사양의 일부입니다. 다르게 동작하는 컴파일러는 C 언어를 따르지 않습니다.
abelenky 2011 년

몰랐습니다, 감사합니다. 이 특별한 경우를 읽을 수있는 리소스를 찾을 수 없습니다. 북마크로 가지고 있으면 좋을 것입니다.
cocoafan 2011 년

1
이를 부분 초기화라고합니다. C99 사양은 없지만 여기에 두 가지 소스가 있습니다. bit.ly/enBC2m "배열의 모든 요소를 ​​초기화 할 필요는 없습니다. 배열이 부분적으로 초기화 된 경우 초기화되지 않은 요소는 값 0을받습니다. 적절한 유형. " bit.ly/f9asHH "배열의 요소보다 이니셜 라이저가 적 으면 나머지 요소는 자동으로 0으로 초기화됩니다."
abelenky 2011 년

이것은 이미 선언되고 값이 할당 된 배열에는 적용되지 않습니까?
skinnedKnuckles 2010 년

10

사용하다:

memset(my_custom_data, 0, sizeof(my_custom_data));

또는:

memset(my_custom_data, 0, strlen(my_custom_data));

1
두 번째 옵션 ( memset(my_custom_data, 0, strlen(my_custom_data));)은 배열의 끝을 넘어 설 수있는 첫 번째 '\ 0'까지만 지워집니다. 이것은 괜찮을 수도 있고 아닐 수도 있습니다.
brewmanz

9

다음 코드를 시도하십시오.

void clean(char *var) {
    int i = 0;
    while(var[i] != '\0') {
        var[i] = '\0';
        i++;
    }
}

2
참고-코드를 4 칸 들여 쓰기하거나 선택하고 두 줄의 바이너리처럼 보이는 '코드'버튼을 누르십시오.
meagar

memset ()에 string.h를 포함하고 싶지 않은 경우 탁월한 솔루션입니다.
Akash Agarwal

7

왜 사용하지 memset()않습니까? 그렇게하는 방법입니다.

첫 번째 요소를 설정하면 나머지 메모리는 그대로 유지되지만 str 함수는 데이터를 비어있는 것으로 처리합니다.


1
memset 함수를 통해 가독성을 사용하지 마십시오 stackoverflow.com/questions/453432/...을
요한 게렐

1
그러면 당신의 대답은 무엇입니까?
mkb 2011

6

Pls는 사례 1 및 사례 2 이후 배열의 데이터로 설명 한 곳을 아래에서 찾습니다.

char sc_ArrData[ 100 ];
strcpy(sc_ArrData,"Hai" );

사례 1 :

sc_ArrData[0] = '\0';

결과:

-   "sc_ArrData"
[0] 0 ''
[1] 97 'a'
[2] 105 'i'
[3] 0 ''

사례 2 :

memset(&sc_ArrData[0], 0, sizeof(sc_ArrData));

결과:

-   "sc_ArrData"
[0] 0 ''
[1] 0 ''
[2] 0 ''
[3] 0 ''

첫 번째 인수를 NULL로 설정하는 것이 트릭을 수행하지만 memset을 사용하는 것이 좋습니다.


4

아니. 당신이하는 일은 첫 번째 값을 '\ 0'또는 0으로 설정하는 것뿐입니다.

null로 끝나는 문자열로 작업하는 경우 첫 번째 예제에서 예상 한 것과 유사한 동작을 얻을 수 있지만 메모리는 여전히 설정되어 있습니다.

memset을 사용하지 않고 메모리를 지우려면 for 루프를 사용하십시오.


for 루프에서 아니오라고 말합니다. 자신의 "개선 된"(일반적으로는 아님) 라이브러리 함수를 작성하지 마십시오. 실제로 memset 및 memcpy는 데이터 정렬 및 길이에 대해 알려진 내용을 기반으로 CPU 용 사용자 정의 기계 코드에 종종 인라인됩니다.
Zan Lynx

@Zan the OP는 memset을 사용하고 싶지 않습니다 (아마도 그는 내장되어 있고 사용할 수 없습니다). 그러나 예, memset은 일반적으로 매우 최적이며 for 루프보다 빠릅니다.
Adam Hawes

사실이지만 그는 memset을 사용하고 싶지 않았기 때문에 for 루프를 제안했습니다.
Alan

3

memset을 사용해야합니다. 첫 번째 요소 만 설정하면 작동하지 않습니다. 모든 요소를 ​​설정해야합니다. 그렇지 않은 경우 어떻게 첫 번째 요소 만 0으로 설정할 수 있습니까?


memset 함수는 가독성을 통해 사용할 수 없습니다 : stackoverflow.com/questions/453432/...
요한 게렐

2

첫 번째 문자에 널 문자를 쓰는 것이 바로 그 일입니다. 이를 문자열로 취급하면 널 종료 문자를 따르는 코드가 널 문자열로 취급하지만 데이터를 지우는 것과는 다릅니다. 실제로 데이터를 지우려면 memset을 사용해야합니다.



1

첫 번째 요소를 null로 설정하면 char 배열의 전체 내용이 지워질 것이라고 생각했습니다.

당신이 발견 한 것은 정확하지 않습니다.

그러나 이것은 첫 번째 요소 만 null로 설정합니다.

바로 그거죠!

모든 데이터를 지우려면 memset을 사용해야합니다. 항목 중 하나를 null로 설정하는 것만으로는 충분하지 않습니다.

그러나 배열의 요소를 null로 설정하면 특별한 의미가있는 경우 (예 : null 종료 문자열을 사용할 때) 첫 번째 요소를 null로 설정하는 것으로 충분할 수 있습니다. 이렇게하면 배열의 모든 사용자가 배열이 여전히 메모리에 이전 문자를 포함하더라도 비어 있음을 이해할 수 있습니다.


: 가독성을 통해 "memset 함수를"사용하지 마십시오 stackoverflow.com/questions/453432/...
요한 게렐

1

첫 번째 요소를 NULL로 설정합니다. 문자 배열을 인쇄하면 아무것도 반환되지 않습니다.



-3
void clearArray (char *input[]){
    *input = ' '; 
}

1
이것은 CLEARING이 아니라 첫 번째 문자를 ''로 설정하는 것입니다! 난 당신이 * 입력을 쓰기 = '\ 0'원 생각
stviper

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.