4 votes

Caractères non définis lors de la lecture du contenu du fichier sans nouvelle ligne à la fin du fichier

Fichier (settings.txt) à analyser :

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

Dans le cas où il n'y a pas d'ENTRÉE " \n "La sortie est :

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

Avec ENTER " \n " à la fin de la sortie du fichier est correcte (sans " řřřř ") :

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

Comment modifier le programme pour qu'il fonctionne sans ajouter de nouvelle ligne à la fin du fichier ? Code :

#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();
}

1voto

arturx64 Points 888

Vous pouvez réécrire votre code de cette manière :

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();

Tout d'abord, vous devez utiliser le drapeau suivant : containerFile >> std::noskipws; Il vous permet d'utiliser les espaces blancs. Les espaces de tabulation, les retours chariot et les espaces vides sont tous considérés comme des espaces blancs. selon la documentation .

Une représentation correcte des chaînes de caractères nécessite Caractère nul à la fin, donc la ligne suivante buffer.push_back('\0'); ajoute \0 à la fin du tampon.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X