程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C++語言的getline在cl和g++中的不同語義

C++語言的getline在cl和g++中的不同語義

編輯:關於C++

本文的cl指的是Visual studio 2010中的的C++語言編譯器,g++指的是g++ 4.9編譯器。getline在cl中指的是獲取的一行中沒帶” ”;而g++中的getline指的是獲取的一行中帶” ”。下面詳述我為什麼注意到這個問題及測試不同平台的代碼。

1 問題產生

我按照書《C++ Primer》1中11.3.6節中a word transformation map程序時發現運行結果不對,我采用的是g++ 4.9.2編譯器。代碼如下:

// A word transformation map
#include
#include 
#include 
#include 
#include 

using namespace std;

map buildMap(ifstream &map_file){
    map trans_map; // holds the transformations
    string key;
    string value; //phrase to use instead
    // read the first word into key and the rest of the line into value
    while(map_file >> key && getline(map_file,value)) {
        if(value.size() >1) // check that there is a transformation
            trans_map[key] = value.substr(1); // skip leading space
        else
            throw runtime_error(no rule for + key);
    }
    return trans_map;
}

const string& transform(const string &s, const map &m) {
    // the actual map work; this part is the heart of the program
    auto map_it = m.find(s);
    //if this word is in the transformation map
    if(map_it != m.cend()) {
        return map_it->second;
    } else
        return s;
}

void word_transform(ifstream &map_file, ifstream &input) {
    auto trans_map = buildMap(map_file);
    string text;
    while(getline(input,text)){ // read a line of inpu
        istringstream stream(text);
        string word;
        bool firstword = true;
        while(stream >> word) {
            if(firstword)
                firstword = false;
            else 
                cout <<  ;
            cout << transform(word,trans_map);
        }
        cout << endl;
    }
}

int main() {
    ifstream in(wordTrans.txt);
    ifstream inputfile(wordTransInput.txt);

    word_transform(in, inputfile);
    return 0;
}

使用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中不帶” ”符。

3 測試平台getline語義的小代碼

如下:

//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!”被系統命令提示符沖掉了。

4 結束語

getline在cl和g++編譯器上面具有不同的語義。如果不認識到這一點,將不能正確理解程序的輸出結果。所以,使用getline函數時要小心。


  • Stanley B. Lippman, Josee Lajoie, Barbara E. Moo. C++ Primer. 5th ed. Upper Saddle River NJ, Addison-Wesley, 2013. ?

     

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved