Почему C++ неправильно читает значения из txt-файлов?

Я сделал программу, которая считывает значение из txt-файла "база данных.txt", но вывод неверен, когда число трехзначное

ifstream myfile("database.txt");
int broj_rijeci = 0;
if (myfile.is_open())
{
    while (getline(myfile, line))
    {
        if (line.at(0) == '[')
        {
            int i = line.length() - 2;
            int brojac = 0;
            system("pause");
            while (line.at(i) != line.at(0))
            {
                input = line.at(i);
                ascii_convert(input);
                broj_rijeci = broj_rijeci + input * pow(10, brojac);
                i--;
                brojac++;
            }
        }
    }
    myfile.close();
}
else cout << "Unable to open file";

и моя база данных выглядит так:

[311]

выход "310"

2 ответов


Так как вы не предоставили реализации ascii_convert трудно сказать, есть ли проблема там или в другом месте. Однако вы можете значительно упростить процесс и устранить необходимость в собственных процедурах преобразования с помощью std::stringstream.

#include <sstream>

std::ifstream myfile("database.txt");
if (myfile.is_open())
{
    std::string line;
    while (std::getline(myfile, line))
    {
        if (line.size() > 1 && line[0] == '[' && line[line.size() - 1] == ']')
        {
            int value;
            if(std::istringstream(line.substr(1, line.size() - 2)) >> value)
            {
                // Conversion was a success ... do something with "value"
            }
            else
            {
                // Conversion failed. Handle error condition.
            }
        }
    }
    myfile.close();
}
else std::cout << "Unable to open file";

исправление вашего кода, чтобы быть SSCCE показывает ожидаемый результат:

 #include <iostream>
 #include <sstream>
 #include <string>
 #include <math.h>

 int main()
 {
     std::istringstream myfile("[311]");
     int broj_rijeci = 0;
     for (std::string line; std::getline(myfile, line); )
     {
         if (2 < line.size() && line.at(0) == '[')
         {
             int i = line.length() - 2;
             int brojac = 0;
             while (line[i] != line[0])
             {
                 char input = line[i];
                 input -= '0';
                 broj_rijeci = broj_rijeci + input * pow(10, brojac);
                 i--;
                 brojac++;
             }
         }
     }
     std::cout << "result=" << broj_rijeci << '\n';
 }

тем не менее, этот код, вероятно, намного медленнее, чем это должно быть. Например, вычисление мощности даже целого числа занимает пару операций на каждой итерации, в то время как на самом деле требуется только одно умножение:

#include <iostream>
#include <sstream>

int main()
{
    std::istringstream in("[311]");
    for (std::string line; std::getline(in, line); ) {
        if (2 < line.size() && line.front() == '[' && line.back() == ']') {
            int result(0);
            for (std::string::const_iterator it(line.begin() + 1), end(line.end());
                 std::isdigit(static_cast<unsigned char>(*it)); ++it) {
                result = result * 10 + *it - '0';
            }
            std::cout << "result=" << result << '\n';
        }
        else {
            std::cout << "ERROR: unexpected format on line '" << line << "'\n";
        }
    }
}