2014-10-29 2 views
1

codeblocks에 strlwr 복제 할 때 :이상한 ASCII 응답 (중국어) 다음 코드는 아주 이상한 결과를 제공 13.12

#include <iostream> 
#include <fstream> 

using namespace std; 

ifstream f("f1.in"); 
ofstream g("f1.out"); 
char sir[255]; 
int i; 

char strlwr(char sir[]) //if void nothing changes 
{ 
    int i = 0; 

    for (i = 0; sir[i] != NULL; i++) { 
     sir[i] = tolower(sir[i]); 
    } 

    return 0; //if instead of 0 is 1 it will kinda work , but strlwr(sir) still needs to be displayed 
} 

int main() 
{ 
    f.get(sir, 255); 
    g << sir << '\n'; // without '\n' strlwr will no more maters 
    g << strlwr(sir); 
    g << sir; 
    return 0; 
} 

f1.in :

JHON HAS A COW 

f1.out :

䡊乏䠠十䄠䌠坏 
桪湯栠獡愠挠睯 

단지 CAPS 만 사용하는 경우에만 표시됩니다.
유럽 버전의 우분투 14에서 Code :: Blocks 13.12를 사용하고 있습니다.
나는 이것이 왜 이것을 보여 주는지에 관심이 많습니다.
나는 그것이 당신에게 똑같은 것을주는 지 알고 싶어합니다.

+0

'f1.in'의 내용은 무엇입니까? [mojibake] (https://en.wikipedia.org/wiki/Mojibake)의 결과 인 것 같습니다. (즉, 텍스트는 ASCII이지만 터미널 또는 출력 파서는 UTF-8이라고 생각합니다.) –

+0

conent는 "JHON HASA COW"이며 모두 결과가 f1.out에 표시됩니다. 나는 ASCII 값이 변경되었다고 생각하지만, 프로그램에서 어디에 있는지, 그리고 '\ n'(endl)을 제거하면 그 일이 더 이상 발생하지 않는 이유는 무엇인가. 모기 베크 (Mojibake)가이 문제와 관련이 있을지 모르지만 문제라고 생각하지 않습니다. – George

+0

출력을 보려면 무엇을 사용하고 있습니까? 'cat f1.out' 또는 텍스트 편집기를 사용 하시겠습니까? –

답변

1

축하합니다! mojibake을 (를) 발견했습니다. 출력 텍스트는 100 % 정확하지만, 그것을 보는 것은 유니 코드로 해석됩니다.

유니 코드 출력을 16 진수 값으로 변환하면 문제가 해결됩니다. (코드 this StackOverflow answer에서 차용.)

$ cat unicode.txt 
䡊乏䠠十䄠䌠坏 
桪湯栠獡愠挠睯 

$ cat unicode.txt | while IFS= read -r -d '' -n1 c; do printf "%02X\n" "'$c"; done 
484A 
4E4F 
4820 
5341 
4120 
4320 
574F 
0A 
686A 
6E6F 
6820 
7361 
6120 
6320 
776F 
0A 

두 번째 명령은 문자로 파일 문자를 읽고 16 진수로 리틀 엔디안 양식을 인쇄합니다. 각 문자가 2 바이트의 데이터 인 이유는 입력이 2 바이트 인코딩 인 UTF-16으로 인식되기 때문입니다. 문제가 당신의 C++ 프로그램이나 보는 프로그램 인 경우

$ cat unicode.txt | while IFS= read -r -d '' -n1 c; do printf "%02X\n" "'$c"; done 
484A ; JH 
4E4F ; ON 
4820 ; H 
5341 ; AS 
4120 ; A 
4320 ; C 
574F ; OW 
0A ; \n 
686A ; jh 
6E6F ; on 
6820 ; h 
7361 ; as 
6120 ; a 
6320 ; c 
776F ; ow 
0A ; \n 

가 확인하려면 : 대신 (그리고 올바른 엔디 언에 대한) 단일 바이트 ASCII로 진수 출력을 재 해석하는 경우

당신은 당신의 프로그램이 작업을 한 것을 볼 수 있습니다 , 다음 명령을 실행하십시오 xxd f1.out. ASCII처럼 보이면 시청 프로그램 오류입니다. 그렇지 않으면 프로그램의 잘못이며 setlocale을보고 바이너리 모드로 출력 파일을 열어야합니다.

어쨌든 g<<strlwr(sir);strlwr(sir);으로 변경해야합니다. 현재 의도하지 않은 출력에 NULL 바이트를 추가하고 있습니다.

+0

strlwr()으로 그 일을 보았지만 왜 st << strlwr (sir)로 strlwr (sir)로 바뀌면 모든 것이 제대로 작동하는지 이해하지 못했습니다. NULL 바이트가 0을 표시해야한다고 생각했습니다. , 최대,하지만이 두 행 사이의 NULL 바이트 모든 것을 변경하는 것을 의미합니다 생각합니다. – George

+0

@George - * 일반적으로 *'0'을 썼지 만 'int'가 아닌'char'을 반환하는 함수를 정의했습니다. '(char) 0'과'(int) 0'의 값은 같지만, 파일에 쓰는 경우 다르게 처리됩니다. –