本文的cl指的是Visual studio 2010中的的C++語言編譯器,g++指的是g++ 4.9編譯器。getline在cl中指的是獲取的一行中沒帶” ”;而g++中的getline指的是獲取的一行中帶” ”。下面詳述我為什麼注意到這個問題及測試不同平台的代碼。
我按照書《C++ Primer》1中11.3.6節中a word transformation map程序時發現運行結果不對,我采用的是g++ 4.9.2編譯器。代碼如下:
// A word transformation map
#include
使用g++ 4.9.2編譯器編譯運行後得到的結果如下:
而采用cl運行的結果如下:
我為g++不能得到正確的輸出結果而著急。我以為cout在輸出的時候沒有flush緩沖區,於是flush命令用了,ends命令也用了,可就是解決不了問題。難道vc那麼神嗎,就能輸出正確的結果。g++也是個優秀的編譯器,為什麼不能輸出正確的結果呢。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoMiBpZD0="2-分析代碼">2 分析代碼
經過認真分析代碼,我將問題的症結歸結為函數buildMap()中的getline上面。我將函數word_transform()中的3個cout改為輸出到文件,結果如下:
很容易我們可以看出,buildMap()中的getline在讀入每行的時候在結尾處增加了一個” ” (換行)。至此,找到問題所在,將上述代碼trans_map[key] = value.substr(1);
改為
trans_map[key] = value.substr(1, value.size()-2);
即可。也就是將最後一個換行符去掉。至此,程序可在g++中能得到正確運行結果。為什麼代碼沒改動前輸出到文件和輸出到屏幕的結果不同,這就牽涉到緩沖區的問題了。我剛開始使用flush緩沖區的方法不成功的原因是getline在作怪,沒找到病源。
可是問題又來了,改動後的代碼在cl中的結果顯示不正常了:
從上面可以清楚地看到,每一個翻譯後的單詞都少了最後一個字母。可以得出,getline在cl中不帶” ”符。
如下:
//This program is used to test the
//getline semantic for g++ or vc
#include
#include
#include
using namespace std;
int main() {
ifstream infile(getlinePtest.txt);
string value;
getline(infile,value);
cout << value ;
getline(infile,value);
cout << value;
}
其中getlinePtest.txt文件中的內容為:
I love China!
I love Beijing!
[空行]
輸出 “I love China!I love Beijing!”為cl編譯器,輸出”I love China!”為g++編譯器,因為”I love Beijing!”被系統命令提示符沖掉了。
getline在cl和g++編譯器上面具有不同的語義。如果不認識到這一點,將不能正確理解程序的輸出結果。所以,使用getline函數時要小心。