gcc 명령줄에서 문자열 리터럴을 정의하려면 어떻게 해야 합니까?
gcc 명령줄에서 다음과 같은 문자열을 정의합니다.-Dname=Mary
원하는 소스 코드에서printf("%s", name);
인쇄하다Mary
.
내가 어떻게 할 수 있겠어?
두 가지 옵션이 있습니다.첫째, 따옴표를 피해서 셸이 따옴표를 먹지 않도록 합니다.
gcc -Dname=\"Mary\"
또는 -Dname=Mary를 꼭 원하신다면, 조금 허술하지만 문자열화 할 수도 있습니다.
#include <stdio.h>
#define STRINGIZE(x) #x
#define STRINGIZE_VALUE_OF(x) STRINGIZE(x)
int main(int argc, char *argv[])
{
printf("%s", STRINGIZE_VALUE_OF(name));
}
STRINGIZE_VALUE_OF는 매크로의 최종 정의까지 평가됩니다.
인용문 및 기타 문자를 "먹어버리는" 껍데기를 피하기 위해 다음과 같은 작은 인용문을 사용할 수 있습니다.
gcc -o test test.cpp -DNAME='"Mary"'
이렇게 하면 정의된 항목(따옴표, 공백, 특수 문자 등)을 완전히 제어할 수 있습니다.
내가 지금까지 발견한 가장 휴대하기 쉬운 방법은\"Mary\"
- gcc뿐만 아니라 다른 C 컴파일러와도 동작합니다.예를 들면,/Dname='"Mary"'
Microsoft 컴파일러에서는 에러와 함께 정지합니다만,/Dname=\"Mary\"
효과가 있습니다.
이것은 다음 용도의 솔루션입니다.-DUSB_PRODUCT=\""Arduino Leonardo\""
make file에 다음과 같이 사용했습니다.
GNU Make 3.81 (GnuWin32에서)
그리고.
avr-g++(AVR_8_bit_)GNU_Toolchain_3.5.0_1662) 4.9.2
사전 컴파일된 파일(-g++의 경우 E 옵션)의 결과는 다음과 같습니다.
const u8 STRING_PRODUCT[] __attribute__((__progmem__)) = "Arduino Leonardo";
Ubuntu에서는 CFLAGS를 정의하는 에일리어스를 사용하고 있으며 CFLAGS에는 문자열을 정의하는 매크로가 포함되어 있어 Makefile에서 CFLAGS를 사용하고 있습니다.큰따옴표와\문자를피해야했습니다.그것은 다음과 같이 생겼습니다.
CFLAGS='" -DMYPATH=\\\"/home/root\\\" "'
다음으로 간단한 예를 제시하겠습니다.
#include <stdio.h>
#define A B+20
#define B 10
int main()
{
#ifdef __DEBUG__
printf("__DEBUG__ DEFINED\n");
printf("%d\n",A);
#else
printf("__DEBUG__ not defined\n");
printf("%d\n",B);
#endif
return 0;
}
컴파일 할 경우:
$gcc test.c
출력:
__DEBUG__ not defined
10
컴파일 할 경우:
$gcc -D __DEBUG__ test.c
출력:
__DEBUG__ defined
30
참고로, 같은 시스템상의 같은 툴 체인의 다른 버전이라도, 이 점에 대해서는 다른 동작을 취할 수 있습니다.(와 같이, 이것은 셸 패싱의 문제라고 생각됩니다만, 셸에만 한정되는 것은 아닌 것 같습니다).
여기에서는 xc32-gcc 4.8.3과 (avr-)gcc 4.7.2(및 다른 몇 가지)를 같은 makefile과 main.c를 사용하고 있습니다.단, 차이점은 다음과 같습니다.'make CC=xc32-gcc'
,기타.
CFLAGS += -D'THING="$(THINGDIR)/thing.h"'
는 수년간 많은 버전의 gcc(및 bash)에서 사용되고 있습니다.
이것을 xc32-gcc 와 호환시키기 위해서(또 다른 코멘트에 비추어 「 「보다 휴대성이 좋다」라고 하는 코멘트에 근거해) 다음의 조작을 실시할 필요가 있었습니다.
CFLAGS += -DTHING=\"$(THINGDIR)/thing.h\"
ifeq "$(CC)" "xc32-gcc"
CFLAGS := $(subst \",\\\",$(CFLAGS))
endif
이것을 발견하는 것을 정말로 혼란스럽게 합니다.따옴표가 없는 -D에 //를 붙이면 #define이 되고 마지막에 코멘트가 붙습니다.
THINGDIR=/thingDir/
->#define /thingDir//thing.h
->#define /thingDir
(여기서 답변해 주셔서 감사합니다, btw
Ubuntu에서 컴파일되지 않는 어플리케이션을 발견했습니다.Linux와 Windows는 공통 접근법에 동의하지 않기 때문에 다음과 같은 방법을 사용했습니다.
NAME := "Mary"
ifeq ($(SystemRoot),)
# building on another OS
CFLAGS_ADD += -Dname=\"Mary\"
else
# building on Windows
CFLAGS_ADD += -Dname=\\\"Mary\\\"
endif
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++.exe build active file",
"command": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe",
"args": [
"-g",
"-DSHERAJ",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "compiler: \"C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe\""
}
]
}
는 난했을 .#define SHERAJ
판돈 VS 판돈경쟁사의 프로그래밍에 매우 적합합니다.
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
#ifdef SHERAJ
freopen("input.txt" , "r", stdin);
#endif
int T;
cin>>T;
for(int test_case = 1;test_case<=T;test_case++) {
cout<<"Hello World"<<endl;
}
}
Mac(윈도우) VS 코드(VS Code)기타 방법은 다음과 같습니다."-Dname=\"SHERAJ\""
★★★★★★★★★★★★★★★★★」"-Dname=\\\"SHERAJ\\\""
효과가 없었습니다.
은 그래 so so so입니다."-DSHERAJ"
언급URL : https://stackoverflow.com/questions/2410976/how-to-define-a-string-literal-in-gcc-command-line
'programing' 카테고리의 다른 글
부동 소수점 값을 비교하는 것은 얼마나 위험한가요? (0) | 2022.08.18 |
---|---|
Vuex, 글로벌 오류 및 알림 처리 모범 사례 (0) | 2022.08.18 |
하위 구성 요소에서 Vuex가 작동하지 않음 (0) | 2022.08.18 |
Vue-repo "모듈 빌드 실패:오류: ESLint 구성을 찾을 수 없습니다." (0) | 2022.08.18 |
정수 기반 전원 함수 pow(int, int)를 구현하는 가장 효율적인 방법 (0) | 2022.08.11 |