2010-02-16 6 views
2
char sXSongBuffer[20][30]; 
sXSongBuffer = {"Thriller", "Don't Stop Till You Get Enough", "Billy Jean"}; 

expected expression before ‘{’ token 오류가 반환됩니까? 이렇게 배열을 초기화하려는 이유는 나중에 내용을 바꿀 수 있기 때문입니다.왜 이런 cstring 배열을 초기화 할 수 없습니까?

sXSongBuffer = {"New Song", "More Music From Me"}; 

답변

6

C에서 배열에 할당 할 수 없습니다. C는 초기화를 허용합니다. 배열은 컴파일 타임 상수 값을 갖습니다. 값을 나중에 변경하거나 컴파일 타임 상수가 아닌 값을 설정하려면 배열의 특정 인덱스에 수동으로 할당해야합니다.

그래서, sXSongBuffer로 할당 배열이 너무있다 sXSongBuffer[0]sXSongBuffer[19]에 있기 때문에, 또한 C에서 허용되지 않습니다, 당신도 말할 수 없다 : sXSongBuffer[0] = "New Song";

을 당신이 원하는에 따라,이 당신을 위해 작동 할 수 있습니다

/* declare sXSongBuffer as an array of pointers */ 
char *sXSongBuffer[30] = { 
    "Thriller", 
    "Don't Stop Till You Get Enough", 
    "Billy Jean", 
    NULL /* set the rest of the elements to NULL */ 
}; 
size_t i; 
/* and then later in your code */ 
sXSongBuffer[0] = "New Song"; 
sXSongBuffer[1] = "More Music From Me"; 
for (i=2; i < sizeof sXSongBuffer; ++i) 
    sXSongBuffer[i] = NULL; 

위의 내용은 컴파일 타임에 모든 문자열을 알고있는 경우에만 작동합니다. 그렇지 않다면 "충분히 큰"배열을 원하는지 아니면 문자열 및/또는 문자열의 수에 동적 메모리가 필요한지 결정해야합니다. 두 경우 모두 strcpy()에 해당하는 문자열을 복사하는 것이 좋습니다.

편집는 :

버프가가 가리키는 즉 당신은 처음 세 요소가 문자열의 크기를 버퍼를 가리키는 30 문자 포인터의 배열을 선언하고 : 주석에 응답하려면 sXSongBuffer[0]"Thriller"보다 큰 문자열을 보유하지 않으며 그는 sXSongBuffer[0] = malloc(32);을 수행하면 작은 메모리 리크가 발생합니다. 또한 배열의 나머지 슬롯 각각에 대해 malloc 메모리를 사용해야합니다. 그는 OP + 지정된 init과 같은 2d char 배열을 사용하거나 런타임에 각 버퍼를 malloc 버퍼에 저장하고 값을 복사해야합니다. 그는 또한 free 어떤 기억을 그는 malloc s 기억해야합니다. char *sXSongBuffer[30];

sXSongBuffer 각 소자는 char *, char 포인터 인 상태, 크기 (30)의 배열이다. 내가 할 때 :

char *sXSongBuffer[30]; 

각 30 포인터는 초기화되지 않습니다.내가 할 때 :

char *sXSongBuffer[30] = { "Thriller", ... }; 

나는 다른 읽기 전용 위치에 포인터를 설정한다. 포인터가 다른 곳으로 "다시 가리키는"것을 방지 할 수있는 방법은 없습니다. 내가 가진 것과 같다 :

위의 코드에서
char *data = "Hello"; 
printf("%s\n", data); 
data = "Hello, world"; 
printf("%s\n", data); 

가, 나중에 더 긴 문자열을 가리 키도록 변경 먼저 data"Hello"에 할당합니다. 내 대답에 위의 코드는 sXSongBuffer[i]을 나중에 다른 것으로 재 할당하는 것 이상을 수행했으며 sXSongBuffer[i]이 포인터이기 때문에 할당이 OK입니다. 특히 sXSongBuffer[0]char *이며 유효한 위치 인 char을 가리킬 수 있습니다.

나중에 말했듯이 문자열이 컴파일 타임에 알려지지 않은 경우이 스키마가 작동하지 않으며 "충분히 큰"크기의 배열을 사용하거나 동적으로 메모리를 할당해야합니다. 충분히 커.

+0

문자열의 크기를 가리키는 처음 세 요소, 즉'sXSongBuffer [0]'이 가리키는 buff은 "Thriller"보다 큰 문자열을 보유하지 않고 30 개의 char 포인터 배열을 선언합니다. if 그는'sXSongBuffer [0] = malloc (32);'그는 작은 메모리 리크를 얻을 것이다. 또한 배열의 나머지 슬롯 각각에 대해 메모리를 malloc해야합니다. 그는 OP + 지정된 init과 같은 2 차원 char 배열을 사용하거나 런타임에 각 버퍼를 malloc하여 값을 복사해야합니다. 그는 또한 그가 mallocs 어떤 기억든지 해방하는 것을 기억할 필요가있을 것이다. –

+0

@ 로버트 : 내 편집을 참조하십시오. –

0

C에는 범용 배열 리터럴이 없습니다. {} 목록 구문은 초기화 할 때만 작동합니다 (예 : 변수를 선언 한 동일한 문에서 값을 할당 할 때).

char * sXSongBuffer[]= {"Thriller", "Don't Stop Till You Get Enough", "Billy Jean"}; 

또는 중 모든 항목에 stnrcpy을 사용합니다 :

0

당신은 당신이 한 번에 배열을 초기화해야 하나 (그러나 그것은 단지 3 항목이 (가) 포함됩니다)

char sXSongBuffer[20][30]; 
sXSongBuffer = {"Thriller", "Don't Stop Till You Get Enough", "Billy Jean"}; 

쓸 수 없습니다

char sXSongBuffer[20][30]; 
strncpy(sXSongBuffer[0],"Thriller",29); 
strncpy(sXSongBuffer[1],"Don't Stop Till You Get Enough",29); 
strncpy(sXSongBuffer[2],"Billy Jean",29); 
+0

그는 그가 원하는 효과를 얻기 위해 지정된 이니셜 라이저를 사용할 수 있습니다. –

0

Designated Initializers을 살펴보십시오.

#include <stdio.h> 

int main (void) { 

    char a[6][6] = { [2] = "foo", [4] = "bar" }; 

    for (int i=0; i<6; ++i) 
     printf("%d == %s\n", i, a[i]); 

    return 0; 
} 

이것은 c99 기능입니다.

gcc -W -std=c99 2dInit.c -o 2dInit 

이 출력 : 컴파일 귀하의 경우

0 == 
1 == 
2 == foo 
3 == 
4 == bar 
5 == 

은 당신이 원하는 :

char sXSongBuffer[20][30] = { 
    [0] = "Thriller", 
    [1] = "Don't Stop Till You Get Enough", 
    [2] = "Billy Jean" 
}; 
관련 문제