2013-10-23 75 views
0

嗨,在我上一個問題中,我能夠獲取結構的數據加載到一個文件上,但現在問題是我得到了垃圾數值檢索它。從二進制文件讀取結構數據時獲取垃圾值

文件內容:settings.bin

110#NormalCompression Level210#NormalCompression Level310#NormalCompression Level410#NormalCompression Level510#NormalCompression Level 

代碼

#include<cstdlib> 
#include<iostream> 
#include<string> 
#include<iomanip> 
#include<fstream.h> 

using namespace std; 

const char* ErrorLogFilePath = "resources\\error.txt"; 
const char* SettingsFilePath = "resources\\settings.bin"; 
const int NoOfSettings = 5; 

struct Setting { 
    int SettingID; 
    int SettingINTValue; 
    double SettingDOUBLEValue; 
    char SettingCHARValue; 
    string SettingSTRINGValue; 
    string SettingName; 
}; 

istream& operator>>(istream& _is, Setting& _s) { 
    _is>>_s.SettingID; 
    _is>>_s.SettingINTValue; 
    _is>>_s.SettingDOUBLEValue; 
    _is>>_s.SettingCHARValue; 
    _is>>_s.SettingSTRINGValue; 
    _is>>_s.SettingName; 
} 

ostream& operator<<(ostream& _os, const Setting& _s) { 
    _os<<_s.SettingID; 
    _os<<_s.SettingINTValue; 
    _os<<_s.SettingDOUBLEValue; 
    _os<<_s.SettingCHARValue; 
    _os<<_s.SettingSTRINGValue; 
    _os<<_s.SettingName; 
} 

class ErrorReport { 
public: 
    fstream ErrorFile; 
    void PostError(string Title,string Data,int ErrorID) { 
     ErrorFile.open(ErrorLogFilePath,ios::out); 
     ErrorFile.close(); 
    } 
} Error; 

class SettingsClass { 
public: 
    Setting setting[NoOfSettings]; 
    void ResetSettings() { 
     fstream SettingFile; 
     Setting defaultsetting[NoOfSettings]; 

     for(int i=1; i<=NoOfSettings; i++) { 
      defaultsetting[i-1].SettingID = i; 
      defaultsetting[i-1].SettingINTValue = 0; 
      defaultsetting[i-1].SettingDOUBLEValue = 0; 
      defaultsetting[i-1].SettingCHARValue = '#'; 
      defaultsetting[i-1].SettingSTRINGValue = "null"; 
      switch(i) { 
      default: 
       defaultsetting[i-1].SettingName = "Compression Level"; 
       defaultsetting[i-1].SettingSTRINGValue = "Normal"; 
       defaultsetting[i-1].SettingINTValue = 1; 
       break; 
      } 
     } 

     SettingFile.open(SettingsFilePath,ios::binary|ios::out); 
     if(SettingFile.is_open()) { 
      for(size_t i=0; i<NoOfSettings; ++i) { 
       SettingFile<<defaultsetting[i]; 
      } 
     } else { 
      cout<<"Error!"; 
     } 
     SettingFile.close(); 

    } 
    void _SettingsClass() { 
     fstream SettingFile; 
     SettingFile.open(SettingsFilePath,ios::binary|ios::in); 
     Setting TempSettings[NoOfSettings]; 
     if(SettingFile.is_open()) { 
      for(size_t i=0; i<NoOfSettings; ++i) { 
       SettingFile>>TempSettings[i]; 
      } 
     } else { 
      cout<<"Error..."; 
     } 
     SettingFile.close(); 
     for(int i=0; i<NoOfSettings; i++) { 
      cout<<TempSettings[i].SettingINTValue<<"\n"; 
     } 
    } 
} Settings; 

int main(int argc, char *argv[]) 
{ 
    Settings._SettingsClass(); 
// cout<<Settings.GetSetting(1).SettingName; 
    system("PAUSE"); 
    return EXIT_SUCCESS; 
} 

輸出

4473076 
1 
3 
0 
2686384 

現在爲什麼我得到這些垃圾值?任何人都可以幫助我,因爲我認爲它不應該像這樣(?)。我應該爲這個struct數組的每個這樣的元素得到1。

在此先感謝!

回答

2

格式化輸入需要分隔符,因此它知道何時停止讀取特定值。即使你用二進制模式打開文件,你寫的文件本質上是一個沒有分隔符的文本文件,所以你不能讀回它。

如果你必須有一個二進制文件,那麼這是讀/使用結構寫一個方式:

#include <iostream> 
#include <string> 
#include <iomanip> 
#include <fstream> 
#include <vector> 

const char* SettingsFilePath = "settings.bin"; 

struct Setting 
{ 
    int SettingID; 
    int SettingINTValue; 
    double SettingDOUBLEValue; 
    char SettingCHARValue; 
    std::string SettingSTRINGValue; 
    std::string SettingName; 

    Setting() 
     : SettingID(0) 
     , SettingINTValue(0) 
     , SettingDOUBLEValue(0) 
     , SettingCHARValue(0) 
    { 
    } 

    void Write(std::fstream& out) 
    { 
     out.write(reinterpret_cast<const char*>(&SettingID), sizeof(SettingID)); 

     out.write(reinterpret_cast<const char*>(&SettingINTValue), sizeof(SettingINTValue)); 

     out.write(reinterpret_cast<const char*>(&SettingDOUBLEValue), sizeof(SettingDOUBLEValue)); 

     out.write(reinterpret_cast<const char*>(&SettingCHARValue), sizeof(SettingCHARValue)); 

     size_t str_size = SettingSTRINGValue.size(); 
     out.write(reinterpret_cast<const char*>(&str_size), sizeof(str_size)); 
     out.write(SettingSTRINGValue.c_str(), SettingSTRINGValue.size()); 

     str_size = SettingName.size(); 
     out.write(reinterpret_cast<const char*>(&str_size), sizeof(str_size)); 
     out.write(SettingName.c_str(), SettingName.size()); 
    } 

    void Read(std::fstream& in) 
    { 
     in.read(reinterpret_cast<char*>(&SettingID), sizeof(SettingID)); 

     in.read(reinterpret_cast<char*>(&SettingINTValue), sizeof(SettingINTValue)); 

     in.read(reinterpret_cast<char*>(&SettingDOUBLEValue), sizeof(SettingDOUBLEValue)); 

     in.read(reinterpret_cast<char*>(&SettingCHARValue), sizeof(SettingCHARValue)); 

     size_t str_size; 
     std::vector<char> str_data; 

     in.read(reinterpret_cast<char*>(&str_size), sizeof(str_size)); 
     str_data.resize(str_size); 
     in.read(&str_data[0], str_size); 
     SettingSTRINGValue.assign(str_data.begin(), str_data.end()); 

     in.read(reinterpret_cast<char*>(&str_size), sizeof(str_size)); 
     str_data.resize(str_size); 
     in.read(&str_data[0], str_size); 
     SettingName.assign(str_data.begin(), str_data.end()); 
    } 

    void Print(const std::string& title) 
    { 
     std::cout << title << "\n"; 
     std::cout << std::string(title.size(), '-') << "\n"; 

     const size_t w = 22; 
     std::cout << std::setw(w) << std::right << "SettingID : " << SettingID << "\n"; 
     std::cout << std::setw(w) << std::right << "SettingINTValue : " << SettingINTValue << "\n"; 
     std::cout << std::setw(w) << std::right << "SettingDOUBLEValue : " << SettingDOUBLEValue << "\n"; 
     std::cout << std::setw(w) << std::right << "SettingCHARValue : " << SettingCHARValue << "\n"; 
     std::cout << std::setw(w) << std::right << "SettingSTRINGValue : " << SettingSTRINGValue << "\n"; 
     std::cout << std::setw(w) << std::right << "SettingName : " << SettingName << "\n"; 

     std::cout << "\n"; 
    } 
}; 

int main() 
{ 
    { 
     Setting s; 
     s.Print("Default before Write"); 

     s.SettingID = 1; 
     s.SettingINTValue = 2; 
     s.SettingDOUBLEValue = 3.5; 
     s.SettingCHARValue = 'Z'; 
     s.SettingSTRINGValue = "Blah Blah"; 
     s.SettingName = "Some Settings"; 

     std::fstream f(SettingsFilePath, std::ios::out | std::ios::binary); 
     s.Write(f); 

     s.Print("Values written to file"); 
    } 

    { 
     Setting s; 
     s.Print("Default before read"); 

     std::fstream f(SettingsFilePath, std::ios::in | std::ios::binary); 
     s.Read(f); 
     s.Print("Values after read"); 
    } 

    return EXIT_SUCCESS; 
} 
+1

謝謝你,你是好的! – Darius967

0

你似乎忘了將你的設置加載到文件中。

int main(int argc, char *argv[]) 
{ 
    Settings.ResetSettings(); // insert code here 
    Settings._SettingsClass(); 
    // cout<<Settings.GetSetting(1).SettingName; 
    system("PAUSE"); 
    return EXIT_SUCCESS; 
}