2013-08-22 2 views
1

나는 이런 식으로 할 수 있습니까?매크로에서 char * 변수의 값 사용

#include <stdio.h> 

#define CAT2(a1, a2) #a1 ## ";" ## #a2 

int main(void) 
{ 
    const char *ch1 = "1"; 
    const char *ch2 = "2"; 
    puts(CAT2(ch1, ch2)); 
} 

출력 :

1, 2

그러나 현재 내가 가지고

CH1, 불행하게도 CH2

+0

'##'의 사용법이 올바르지 않습니다. 이 연산자는 토큰을 문자열이 아닌 유효한 다른 토큰으로 연결하는 데 사용됩니다. 문자열 리터럴의 경우에는 이들을 조인 할 필요가 없으며 인접한 문자열 리터럴은 나중에 컴파일 단계에서 조인됩니다. –

답변

1

매크로 이후 변수의 값을 사용할 수없는 컴파일 타임에 eveluated됩니다. 이것은 매크로의 주요 제한 요소입니다. 나는. 런타임 값을 평가할 수 없습니다.

1

매크로를 사용하여 원하는 방식으로 문자열 연결을 수행 할 수 없습니다.

char tmp[20]; 
snprintf(tmp, sizeof(tmp), "%s;%s", ch1, ch2); 

매크로 실제 컴파일 전에 컴파일시에 확장된다, 그리고 런타임 값을 알 수 없습니다 : 순서

를 사용하여 현재 snprintf은 문자열을 준비합니다.

tmp를 반환하는 함수에 코드를 래핑 할 수 있습니다 (누출을 방지하기 위해 tmp 정적 변수를 만드는 것을 잊지 마세요).

char* cat2(char *ch1, char* ch2) 
{ 
    static char tmp[50]; 
    snprintf(tmp, sizeof(tmp), "%s;%s", ch1, ch2); 
    return tmp; 
} 

// inside main 
puts(cat2(ch1, ch2)); 
2

# operator 리터럴 문자열로 그에게 주어진 매개 변수를 대체합니다.

16.3.2 # 개 연산자 [cpp.stringize]

문자열 리터럴는이다 : 표준에서

#define TO_STR(arg) #arg 

const char* ch1 = "1"; 
TO_STR(ch1) // <- Will give "ch1" 

:

그것은 것을 의미 문자열 - 리터럴 접두사가 없습니다. 바꾸기 목록에서 매개 변수 앞에 # 사전 처리 토큰이 있으면 해당 인수에 대한 전처리 토큰 시퀀스의 철자가 들어있는 단일 문자 문자열 리터럴 사전 처리 토큰으로 바뀝니다.

은 그래서 경우에 있습니다 (## operator와) 연결하는 시도 : 당신이 얻을 결과를 설명

"ch1" ## ";" ## "ch2" 

합니다.

MACRO는 전처리 시간에 평가되므로 변수를 원하는 방식으로 연결할 수 없습니다.

C 인 경우 예를 들어 strcat을 사용해야합니다.

C++을 사용하는 경우 std::string을 사용하거나 C++ 11에서 snprintf을 사용할 수 있습니다.