2016-07-08 74 views
1

我正在C++中製作平鋪引擎/遊戲。我所苦惱的是,我無法弄清楚如何從文件加載和處理整數數據。無法正確讀取文件中的整數C++

這裏是mapfile.map:

[[email protected] ~]$ cat cpp/adventures_of_ironville/mapfile.map 
0000001111101111 
0000111000020000 
1100000000000000 
0100200000111000 
0110000000111200 
0010002200111120 
2010002220111111 
0010022200001111 
0000001111101111 
0000111000020000 
1100000000000000 
0100200000111000 
0110000000111200 
0010002200111120 
2010002220111111 
0010022200001111 
[[email protected] ~]$ 

這是要在我的比賽水平。現在,對於代碼,我掙扎:

bool World::loadLevelFromDisk(std::string pathToMapFile) 
{ 
    //Our file object 
    std::ifstream file(pathToMapFile); 

    //Store contents of file 
    char tempData; 

    if (!file.is_open()) { 
     //Error... 
     return false; 
    } else { //File is ready to use 
     while (!file.eof()) 
     { 
      //Grab one character. 
      tempData = file.get(); 

      //Convert that character 
      //to ascii integer. 
      int data = tempData - 48; 

      //std::vector used elsewhere, 
      //which must take an int. 
      currentLevel.push_back(data); 

      //Why does this output a bunch of -38's? 
      //expected output is to be identical to the 
      //mapfile.map. 
      std::cout << data; 
     } 
    } 
} 

去年性病的輸出::法院:

0000001111101111-380000111000020000-381100000000000000-380100200000111000-380110000000111200-380010002200111120-382010002220111111-380010022200001111-380000001111101111-380000111000020000-381100000000000000-380100200000111000-380110000000111200-380010002200111120-382010002220111111-380010022200001111-38-49 

我怎樣才能從文件中讀取整型數據?我花了很多時間嘗試不同的解決方案,從串流到boost :: lexical_cast,我還沒有找到可行的答案。這是我得到的最接近預期結果的文件,它將整個文件讀取爲可以在其他地方操作。所有幫助非常感謝!

+0

備註:不要使用'file.eof'。用'file.good()'檢查它,或者使用內置的運算符if(file)'。 – Blacktempel

+0

我可以問一下不使用file.eof()的原因嗎? – JohnBobSmith

+3

請參閱stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong查看如何以及爲什麼要從文件中正確讀取。 – iksemyonov

回答

3

的-38實際上是line feed\n字符) 你讀10(用於換行符ASCII碼,然後計算10 - 48)

只是這種修改在你的代碼中省略掉:

... 
tempData = file.get(); 
if (tempData == '\n' || tempData =='\r') continue; 
... 

\r字符只適用於窗戶,但不傷害要格外小心。

另一種方法是簡單地忽略任何東西,這不是一個數字,在這種情況下,條件是:

if (tempData < '0' || tempData > '9') continue; 
+0

哇!非常感謝你!改變eof循環條件刪除多餘的-49,並做這裏建議的問題解決了我的問題! – JohnBobSmith

1

我注意到了有關你的代碼的第一件事是你使用!file.eof()這幾乎總是循環壞事:

參見:比,你是不是隻檢查來選擇你要轉換的字符代碼Why is iostream::eof inside a loop condition considered wrong?

其他(如在其他答案中提到)。

std::vector<char> currentLevel; 

bool loadLevelFromDisk(std::string pathToMapFile) 
{ 
    //Our file object 
    std::ifstream file(pathToMapFile); 

    if(!file.is_open()) 
    { 
     //Error... 
     return false; 
    } 

    //File is ready to use 

    //Store contents of file 
    char tempData; 

    // grab one char 
    while(file.get(tempData)) // never loop on eof() 
    { 
     // you only get here if file.get() was a success 

     if(tempData < '0' || tempData > '9') 
      continue; // ignore irrelevant characters 

     //Convert that character 
     //to ascii integer. 
     int data = tempData - '0'; // more portable 

     //std::vector used elsewhere, 
     //which must take an int. 
     currentLevel.push_back(data); 

     std::cout << data; 
    } 

    return true; // don't forget to indicate success 
} 

如果函數成功,您忘了返回true。如果增加編譯器的警告級別(我使用-Wall -Wextra -pedantic-errorsGCC),則會檢測到此錯誤。