2013-05-30 4 views
5

문자 배열의 데이터로 문자 배열을 초기화하고 싶습니다. 나는 이것에 대한 다음과 같은 코드를 작성 :memset 및 memcpy를 올바르게 사용하여 C++에서 문자 배열을 초기화하십시오.

(친절 실제로이 코드는 따라서 더 큰 뭔가 그 구조와 그 사용의 기묘에 맞게 예정이다 .. 나는 구조와 모두와 함께하고있는 무슨 변명) 그 일이 왜

(rh4dev01:~/rough) rghosh> ./crptr 
Size of `c` variable is : 16 
Value of padding is calculated to be : 10 
sizeof segment_listing is 16 
Ritwik   °× 
(rh4dev01:~/rough) rghosh> ./crptr 
Size of `c` variable is : 16 
Value of padding is calculated to be : 10 
sizeof segment_listing is 16 
Ritwik   Ñ 
(rh4dev01:~/rough) rghosh> ./crptr 
Size of `c` variable is : 16 
Value of padding is calculated to be : 10 
sizeof segment_listing is 16 
Ritwik   g 
(rh4dev01:~/rough) rghosh> ./crptr 
Size of `c` variable is : 16 
Value of padding is calculated to be : 10 
sizeof segment_listing is 16 
Ritwik   pô 
(rh4dev01:~/rough) rghosh> ./crptr 
Size of `c` variable is : 16 
Value of padding is calculated to be : 10 
sizeof segment_listing is 16 
Ritwik 
(rh4dev01:~/rough) rghosh> ./crptr 
Size of `c` variable is : 16 
Value of padding is calculated to be : 10 
sizeof segment_listing is 16 
Ritwik   àå 
(rh4dev01:~/rough) rghosh> ./crptr 
Size of `c` variable is : 16 
Value of padding is calculated to be : 10 
sizeof segment_listing is 16 
Ritwik   » 
(rh4dev01:~/rough) rghosh> ./crptr 
Size of `c` variable is : 16 
Value of padding is calculated to be : 10 
sizeof segment_listing is 16 
Ritwik   pZ 

당신이 설명해 주시겠습니까 : 내 코드를 실행하면

#include <iostream> 
#include <string> 

struct ABC 
{ 
    char a; 
    char b; 
    char c[16]; 
}; 

int main(int argc, char const *argv[]) 
{ 
    struct ABC** abc; 
    std::string _r = "Ritwik"; 
    const char* r = _r.c_str(); 

    if (_r.length() <= sizeof((*abc)->c)) 
    { 
     int padding = sizeof((*abc)->c) - _r.length(); 

     std::cout<<"Size of `c` variable is : "<<sizeof((*abc)->c)<<std::endl; 
     std::cout<<"Value of padding is calculated to be : "<<padding<<std::endl; 

     char segment_listing[ sizeof((*abc)->c)]; 

     std::cout<<"sizeof segment_listing is "<<sizeof(segment_listing)<<std::endl; 

     memcpy(segment_listing, r, _r.length()); 
     memset((segment_listing + _r.length()), ' ', padding); 

     std::cout<<segment_listing<<std::endl; 

    } 
    return 0; 
} 

그러나, 나는 나의 문자열의 끝이 이상한 문자를 얻을? 문자 배열 만 인쇄하기 때문에 길이는 16 문자 뿐이므로 16 문자 만 인쇄하면 안 됩니 까? 그 두 명 (때로는 제로 가끔은 하나의 문자)이 어디에서 오는가?

더 중요한 것은, 내 패딩에 의해 (내 문자 배열 c)에 속하지 않은 메모리가 손상 되었습니까?

+2

에는 널 문자 없다 (차이가있다). 'memcpy','memset' 또는 c-style 배열을 사용하는 정확한 방법은 전혀 아닐 것입니다. 너는 무엇을 달성하려고하는 것 외에? – Grizzly

+0

@JohnDibling 그것은 c와 C++를 혼합하기 때문에 무서운가? – Chani

+1

표준은 구현을 위해 전역 네임 스페이스에서 밑줄로 시작하는 이름을 예약하기 때문에'_r'은 이름에 나쁜 생각입니다. –

답변

2

문자열을 NUL 종료해야합니다.

memcpy(segment_listing, r, _r.length()); 
    memset((segment_listing + _r.length()), ' ', padding-1); 
    segment_listing[_r.length() + padding - 1] = '\0'; 

아마도 당신은 더 나은 당신을 위해 터미네이터를 추가 할, snprintf()를 사용하여 제공 될 것입니다 :

snprintf(segment_listing, sizeof(segment_listing), "%-*s", 
      (int)sizeof(segment_listing)-1, r); 
+0

그리고 문자열을 단지 ""Ritwik "'으로 만들고 패딩으로 공백을 넣지 않으려면'strncpy (segment_listing, r, _r.length()); ' –

+0

감사합니다. 하지만 배열이 null로 끝나지 않았을 때 어떤 변화가 있는지 물어볼 수 있습니까? gcc는 16 개의 배열 만 선언했다는 것을 알고있다. 16자를 인쇄 한 후에 멈추어야합니까? 또한, 메모리를 손상시킬 수 있는지 알려주시겠습니까? (현재 구현에서는 수정 후가 아닙니다) – Chani

+0

출력에 전달 된 포인터에서 읽기를 중단해야하는 시점을 'cout'이 알고 있도록 NUL 터미네이터가 필요합니다. 루틴. – jxh

2

C 문자열은 당신이 어디를 차지 havn't는 0 바이트로 종료된다. 값을 0으로 문자열을 종료해야하며 모든 계산시 추가 바이트를 고려해야합니다.

2

나는 당신의 질문은 C++이 아닌 C로 의미 가정`표준 : cout`의 사용을 가정 segment_listing

-1
const int SIZE = 16; //or 17 if you want 16 + null char 
//pre-initialise array - then will automatically be null terminated 
char segment_listing[SIZE] = {0}; 
+0

잘 모르겠다. – Chani

+0

'memset()'호출로 모방 할 수있다. 버퍼의 마지막 문자를 덮어 쓰면 터미네이터가 손실 될 수 있습니다. 명시 적으로 배치하는 것이 더 안전합니다. – jxh

+0

'const'가 아니라'constexpr'이 필요합니다. – BatchyX

관련 문제