2014-02-07 80 views
1

我一直在尋找一個錯誤代碼,我正在使用有限元方法。重點是我必須從文件中獲取一些數據來識別單元的材料。這個material_id的類型是unsigned char,這是問題所在。從文件到無符號字符變量賦值的奇怪行爲

從文件讀取數據時,將值分配給unsigned char變量的不同方式會得到不同的結果。我已經解決了這個問題,但我仍然想知道爲什麼它以不同的方式工作。這裏有一個樣本代碼再現不同的行爲:

#include <map> 
#include <sstream> 
#include <fstream> 
#include <string> 
#include <iostream> 
#include <vector> 
#include <stdlib.h> 

namespace types 
{ 
//typedef unsigned int material_id; 
typedef unsigned char material_id; 
} 

namespace Utilities 
{ 
    int string_to_int(const std::string & str) 
    { 
    return atoi(str.c_str()); 
    } 
} 

template<typename Number> 
void parseVector_1(std::ifstream & myfile, 
        std::vector<Number> & mat_id) 
{ 
    Number num; 
    std::string line, bin; 

    if (myfile.is_open()) 
    { 
    getline (myfile,line); 
    std::istringstream iss(line); 
    while (iss.good()) 
    { 
     iss >> bin;       // option 1 
     num = Utilities::string_to_int(bin); // option 1 
     mat_id.push_back(num); 
    } 
    } 
    else std::cout << "Unable to open file"; 
} 

template<typename Number> 
void parseVector_2(std::ifstream & myfile, 
        std::vector<Number> & mat_id) 
{ 
    Number num; 
    std::string line, bin; 

    if (myfile.is_open()) 
    { 
    getline (myfile,line); 
    std::istringstream iss(line); 
    while (iss.good()) 
    { 
     iss >> num; // option 2 
     mat_id.push_back(num); 
    } 
    } 
    else std::cout << "Unable to open file"; 
} 

int main() 
{ 
    unsigned int n_mat; 

    std::vector<types::material_id> mat_id_1; 
    std::vector<types::material_id> mat_id_2; 
    std::map<types::material_id, double> D1v; 

    D1v[0] = 0.0; 
    D1v[1] = 1.0; 
    D1v[2] = 2.0; 
    D1v[3] = 3.0; 
    D1v[4] = 4.0; 

    std::ifstream myfile1 ("materials.dat"); 
    parseVector_1(myfile1, mat_id_1); 
    myfile1.close(); 


    std::ifstream myfile2 ("materials.dat"); 
    parseVector_2(myfile2, mat_id_2); 
    myfile2.close(); 

    n_mat = mat_id_1.size(); 
    std::cout << "option 1: "; 
    for (unsigned int i = 0; i < n_mat; ++i) 
    std::cout << "mat["<<i<<"]=" << D1v[mat_id_1[i]] << " "; 
    std::cout << std::endl; 

    n_mat = mat_id_2.size(); 
    std::cout << "option 2: "; 
    for (unsigned int i = 0; i < n_mat; ++i) 
    std::cout << "mat["<<i<<"]=" << D1v[mat_id_2[i]] << " "; 
    std::cout << std::endl; 

    return 0; 

} 

的 「materials.dat」 文件的內容是以下行:

這裏是執行的輸出:

$ unsignedchar_problem.exe 
option 1: mat[0]=0 mat[1]=1 mat[2]=2 mat[3]=3 mat[4]=4 
option 2: mat[0]=0 mat[1]=0 mat[2]=0 mat[3]=0 mat[4]=0 mat[5]=0 

任何人都可以提供一些見解,爲什麼選項1工作正常,但選項2不是?它是否依賴於它的編譯器/平臺總是這樣?

作爲附加的信息,問題是因爲material_id類型通過在他的計算機的其他用戶定義爲unsigned int,所以這是工作沒有任何問題。

回答

1

從istream中提取unsigned char讀取單個字符並將該字符的數值存儲到目標變量中。因此mat_id_2[0]將包含數字值'0',這可能是48(如果您的系統是ASCII)。

提取非字符整數類型將讀取整數並存儲該整數的值,就像您期待的那樣。

+0

謝謝。這聽起來像是正確的解釋。我並不期待它如此簡單......很高興知道。 – sebas