2017-01-10 7 views
4

ファイル(たsettings.txt)ファイルの内容を読みながら:場合未定義文字ファイルの末尾に改行せずに解析する

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

をなし「N \」ENTER出力とされています:

MapKey= FULLSCREEN  MapValue= On 
MapKey= V_SYNC MapValue= Onřřřř 
ファイル出力の末尾に「\ n」はEnterで

は(「RRRR」なし)が正しいです:

のaddiなしで動作するようにプログラムを変更する方法
MapKey= FULLSCREEN  MapValue= On 
MapKey= V_SYNC MapValue= On 

ファイルの終わりに改行しますか?コード:

#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());' - ヌルで終了する不適切な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

関連する問題