C/C ++ 문자열 리터럴에서 알려지지 않은 메타 문자?
-
13-09-2019 - |
문제
다음 코드 세그먼트로 새 프로젝트를 만들었습니다.
char* strange = "(Strange??)";
cout << strange << endl;
다음 출력 결과 :
(이상한
따라서 '??)' -> ']' '번역
그것을 디버깅하면 내 char* string literal이 실제로 그 값이며 스트림 번역이 아님을 보여줍니다. 이것은 분명히 내가 본 메타 문자 순서가 아닙니다. 아마도 일종의 유니 코드 또는 넓은 숯 시퀀스? 나는 그렇게 생각하지 않습니다 ... 나는 모든 관련 프로젝트 설정을 비활성화하려고 시도했습니다.
누구든지 설명이 있습니까?
- 검색 : '물음표, 물음표, 닫기 브레이스'C C ++ 문자열 리터럴
해결책
당신이보고있는 것은 a라고합니다 트리 그라프.
어른들의 서면 언어로, 하나의 물음표만으로도 모든 상황에 충분합니다. 한 번에 하나 이상을 사용하지 않으면 다시는 볼 수 없습니다.
GCC는 기본적으로 Trigraph를 무시합니다. 누구나 의도적으로 사용하지 않기 때문입니다. 그들과 함께 활성화하십시오 -trigraph
옵션 또는 컴파일러에게 -Wtrigraphs
옵션.
Visual C ++ 2010은 또한 기본적으로이를 비활성화하고 제안합니다. /Zc:trigraphs
그들을 가능하게합니다. 이전 버전에서이를 활성화하거나 비활성화하는 방법에 대해서는 아무것도 찾을 수 없습니다.
다른 팁
Trigraph Surprise를 피하는 쉬운 방법 : "?" 문자리 문자 그대로 :
char* strange = "(Strange??)";
char* strange2 = "(Strange?" "?)";
/* ^^^ no punctuation */
편집하다
GCC는 Trigraphs에 대해 경고 할 수있는 옵션이 있습니다. -Wtrigraphs
(활성화 -Wall
또한)
최종 편집
표준의 인용문
5.2.1.1 Trigraph sequences 1 Before any other processing takes place, each occurrence of one of the following sequences of three characters (called trigraph sequences13)) is replaced with the corresponding single character. ??= # ??) ] ??! | ??( [ ??' ^ ??> } ??/ \ ??< { ??- ~ No other trigraph sequences exist. Each ? that does not begin one of the trigraphs listed above is not changed.
5.1.1.2 Translation phases 1 The precedence among the syntax rules of translation is specified by the following phases. 1. Physical source file multibyte characters are mapped, in an implementation-defined manner, to the source character set (introducing new-line characters for end-of-line indicators) if necessary. Trigraph sequences are replaced by corresponding single-character internal representations.
그것은 a입니다 트리 그라프!
??)은 a 트리 그라프.
그게 트리 그라프 지원하다. 문자를 피함으로써 트리 그라프 해석을 방지 할 수 있습니다.
char* strange = "(Strange?\?)";
그것은 a입니다 트리 그라프.
트리 그라프 이유입니다. 이 기사의 C에 대한 이야기는 C ++에도 적용됩니다.
여러 번 언급했듯이, 당신은 trigraph에 물렸다. 자세한 내용은이 이전 SO 질문을 참조하십시오.
'?'를 사용하여 문제를 해결할 수 있습니다. '?'에 대한 탈출 시퀀스 캐릭터:
char* strange = "(Strange\?\?)";
사실, 이것은 탈출 시퀀스의 이유입니다. 이는 그 망할 트리 그라그를 알지 못하면 다소 신비합니다.
GCC에서 크로스 컴파일을 시도하는 동안 내 시퀀스를 트리 그라프:
따라서 지금해야 할 일은 기본적으로 프로젝트에서이를 비활성화하는 방법을 알아내는 것입니다. (어쨌든 미국 키보드 레이아웃을 사용하고 있습니다)
GCC의 기본 동작은 무시하지만 경고를주는 것입니다. 경고는 훨씬 더 세심하며 실제로 Visual Studio 2010이 내가 아는 한 표준으로 채택 할 것입니다.