2017-01-10 27 views
4

文件(SETTINGS.TXT)的端部不讀新行的文件內容進行解析:未定義字符,而在文件

FULLSCREEN=On 
V_SYNC=On [no "\n" at the end of file] 

萬一沒有ENTER「\ n」個輸出是:

MapKey= FULLSCREEN  MapValue= On 
MapKey= V_SYNC MapValue= Onřřřř 

隨着ENTER「\ n」的文件輸出的到底是正確的(沒有「RRRR」):

MapKey= FULLSCREEN  MapValue= On 
MapKey= V_SYNC MapValue= On 

如何更改程序而不ADDI工作在文件的末尾添加新行?代碼:

#include<iostream> 
#include<fstream> 
#include<sstream> 
#include<vector> 
#include<cstdint> 
#include<memory> 


int main() 
{ 
    std::vector<std::pair<std::string, std::string>> container; 
    std::ifstream containerFile("settings.txt", std::ifstream::binary); 
    containerFile.seekg(0, containerFile.end); 
    std::uint64_t fileSize = containerFile.tellg(); 
    containerFile.seekg(0); 
    std::unique_ptr<char> fileBuffer(new char[fileSize]); 
    containerFile.read(fileBuffer.get(), fileSize); 

    std::istringstream fileContent(fileBuffer.get()); 
    std::string fileLine; 
    while (std::getline(fileContent, fileLine)) 
    { 
     std::istringstream bufferLine(fileLine); 
     std::string option; 
     if (std::getline(bufferLine, option, '=')) 
     { 
      std::string value; 
      if (std::getline(bufferLine, value)) 
      { 
       container.emplace_back(make_pair(option, value)); 
      } 
     } 
    } 
    for (auto &element : container) 
    { 
     std::cout << "MapKey= " << element.first << " MapValue= " << element.second << std::endl; 
    } 
    containerFile.close(); 
} 
+0

'std :: istringstream fileContent(fileBuffer.get());' - 一個不正確的以null結尾的char緩衝區被轉換爲std :: string。有很多方法可以解決這個問題,比如顯式構造字符串的長度:'std :: istringstream fileContent(std :: string(fileBuffer.get(),fileSize));' –

+0

如果這是一個Windows系統,並且如果這是一個標準的文本文件,使用'std :: ifstream :: binary'讀取會在每個換行符之前保留額外的回車符:('「\ r \ n」'),這也可能導致解析問題。 –

回答

1

你可以重寫你的代碼是這樣的:

std::vector<std::pair<std::string, std::string>> container; 
std::ifstream containerFile("settings.txt"); 
containerFile.seekg(0, containerFile.end); 
std::uint64_t fileSize = containerFile.tellg(); 
containerFile.seekg(0); 

/* Changed code. Begin*/ 
containerFile >> std::noskipws; 
std::vector<char> buffer; 
buffer.reserve(fileSize); 
std::copy(std::istream_iterator<char>(containerFile), std::istream_iterator<char>(), std::back_inserter(buffer)); 
buffer.push_back('\0'); 
std::istringstream fileContent(&buffer.front()); 
/* Changed code. End*/ 

std::string fileLine; 
while (std::getline(fileContent, fileLine)) 
{ 
    std::istringstream bufferLine(fileLine); 
    std::string option; 
    if (std::getline(bufferLine, option, '=')) 
    { 
     std::string value; 
     if (std::getline(bufferLine, value)) 
     { 
      container.emplace_back(make_pair(option, value)); 
     } 
    } 
} 
for (auto &element : container) 
{ 
    std::cout << "MapKey= " << element.first << " MapValue= " << element.second << std::endl; 
} 
containerFile.close(); 

首先,你必須使用下一個標誌:containerFile >> std::noskipws; 它允許您使用空格。標籤空格,回車符和空格都被認爲是空白according to documentation

正確的字符串表示形式最後需要Null character,所以下一行buffer.push_back('\0');將'\ 0'添加到緩衝區的末尾。

+0

我不明白爲什麼'\ 0'需要添加。如果這是一個ASCIIZ C字符串,是的。但是對於一個C++字符串,它不是必需的。 – SJHowe