拼音魔法-华东师范大学程序设计竞赛-3256-EOJ
ECNUOJ上的一道题目《拼音魔法》
以下上WA代码
1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 using namespace std; 5 6 //typedef basic_wstring<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring; 7 wchar_t NSCII[][6] = 8 { 9 {L'a',L'o',L'e',L'i',L'u',L'ü'}, 10 {L'ā',L'ō',L'ē',L'ī',L'ū',L'ǖ'}, 11 {L'á',L'ó',L'é',L'í',L'ú',L'ǘ'}, 12 {L'ǎ',L'ǒ',L'ě',L'ǐ',L'ǔ',L'ǚ'}, 13 {L'à',L'ò',L'è',L'ì',L'ù',L'ǜ'} 14 }; 15 16 int findNum(const wstring s) 17 { 18 int size = s.size(); 19 if(size == 0) return 0; 20 int num = s.at(size-1)-L'0'; 21 if(num >= 1 && num <= 4){ 22 return num; 23 } 24 return 0; 25 } 26 27 void findNoteLoc(const wstring s, int v[]) 28 { 29 for(int i = s.size() - 1; i >= 0; i--) 30 { 31 // cout<<"i="<<i<<endl; 32 switch(s.at(i)) 33 { 34 case L'a':v[0] = i;break; 35 case L'o':v[1] = i;break; 36 case L'e':v[2] = i;break; 37 case L'i':v[3] = i;break; 38 case L'u':v[4] = i;break; 39 case L'v':v[5] = i;break; 40 default:break; 41 } 42 } 43 } 44 45 wchar_t changeNote(const int loc[], const int note, int &index) 46 { 47 wchar_t ans = 0; 48 int i = 0; 49 for(; i < 6; i++) 50 { 51 if(loc[i] != -1) 52 { 53 index = loc[i]; 54 //i,u并行标在后 55 if(i == 3 && -1 != loc[4]){ 56 if(loc[3]<loc[4]){ 57 index = loc[4]; 58 i = 4; 59 } 60 } 61 break; 62 } 63 } 64 // cout<<"note is "<<note<<", i is "<<i<<endl; 65 ans = NSCII[note][i]; 66 return ans; 67 } 68 69 /* if true , v to u; if false v to ü */ 70 bool vtou(wstring &s, int loc[]) 71 { 72 if(s.size() != 0) 73 { 74 wchar_t loc0 = s.at(0); 75 if(loc[5] != -1) { 76 if(loc0 == L'y' || loc0 == L'j' || loc0 == L'q' || loc0 == L'x') 77 { 78 return true; 79 } 80 else 81 { 82 return false; 83 } 84 } 85 } 86 return false; 87 } 88 89 int main() 90 { 91 setlocale(LC_ALL, ""); 92 int T; 93 cin>>T; 94 for(int i = 1; i <= T; i++) 95 { 96 wstring s; 97 wcin>>s; 98 int note = findNum(s); // note 音调 99 // cout<<"note is "<<note<<endl; 100 int loc[6]; 101 for(int i = 0; i < 6; i++) 102 { 103 loc[i] = -1; 104 } 105 findNoteLoc(s, loc); 106 int index = -1; // 音调位置 107 wchar_t target = changeNote(loc, note, index); 108 // wcout<<"target is "<<target<<endl; 109 if(loc[5] != -1 && index != loc[5]) // v 不是音调 110 { 111 if(vtou(s, loc)) 112 s.at(loc[5]) = L'u'; 113 else 114 s.at(loc[5]) = L'ü'; 115 } 116 else 117 { 118 if(vtou(s, loc)) 119 target = NSCII[note][4]; 120 } 121 // cout<<index<<endl; 122 if(index != -1) 123 s.at(index) = target; 124 if(note != 0) 125 s.pop_back(); 126 printf("Case %d: %ls\n", i, s.c_str()); 127 } 128 return 0; 129 }
在Mac上这段代码运行测试Case都没任何问题。但是,放到Win上使用Codeblocks编译执行,注音的字符就是打印不出来。扎铁了,目前还在研究中...
Update 2017-06-06
问题找到了:
在一个程序中不能混用cin和wcin,如果确实需要,可调用freopen清除一个流的定向或者fwide函数设置流的定向。
关于这个问题,《Unix环境高级编程》v3的第五章《标准IO库》中详细提到。