Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.91/34: Рейтинг темы: голосов - 34, средняя оценка - 4.91
1 / 1 / 0
Регистрация: 23.03.2020
Сообщений: 3

Неправильная работа stod, from_chars, strtod в MSVC

26.08.2021, 11:31. Показов 6953. Ответов 4

Студворк — интернет-сервис помощи студентам
Добрый день. Столкнулся с проблемой и не смог найти решение. В работе программы постоянно просиходит получение / конвертация чисел с плавающей запятой в строки и обратно, как при чтении файлов-настроек так и при парсинге ответов от сервера, в частности, в json-формате.
Суть проблемы проиллюстрирую на примерах ниже:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
ifstream ifile1("example1.txt");
            if (!ifile1) { cerr << "Cannot read file" << endl; return -1; }
 
        string str_dbl; double dbl = 0.0;
 
        //читаем 298919.55 (разделитель - точка)
        getline(ifile1, str_dbl, ';'); 
 
        dbl = stod(str_dbl);
        cout << dbl << endl;//298920 - округление в большую!
 
        dbl = strtod(str_dbl.c_str(), nullptr);
        cout << dbl << endl;//298920
 
        //на поле выезжают танки
        std::istringstream iss1(str_dbl);
        iss1 >> dbl;
        cout << dbl << endl; //298920 с std::locale().global(std::locale("eng"));
        //cout << dbl << endl; //298919 с std::locale().global(std::locale("rus"));
 
        auto [ptr1, ec1] = from_chars(str_dbl.data(), str_dbl.data() + str_dbl.size(), dbl);
        std::cout << "Result: " << dbl << " ptr->" << std::quoted(ptr1) << endl; //Result: 298920 ptr->""
 
        
        //читаем 298919,55 (разделитель - запятая)
        getline(ifile1, str_dbl, ';'); 
 
        dbl = stod(str_dbl);
        cout << dbl << endl;//298919 - округление в меньшую!
 
        dbl = strtod(str_dbl.c_str(), nullptr);
        cout << dbl << endl;//298919
 
        auto [ptr2, ec2] = from_chars(str_dbl.data(), str_dbl.data() + str_dbl.size(), dbl);
        std::cout << "Result: " << dbl << " ptr->" << std::quoted(ptr2) << endl; //298919 ptr->",55" //отбросил всё что после запятой в char*
 
        std::istringstream iss2(str_dbl);
        iss2 >> dbl;
        cout << dbl << endl; //298919
        //cout << dbl << endl; //298920 c std::locale().global(std::locale("rus"));
        //cout << dbl << endl; //0 c std::locale().global(std::locale("eng"));
 
        ifile1.close();
 
 
        //json, из-за которого и пишется вопрос
        //необходимо #include "nlohmann/json.hpp"
 
        ifstream ifile2("example2.txt");
        if (!ifile2) { cerr << "Cannot read file" << endl; return -2; }
        string page, line;
        while (getline(ifile2, line))
            page += line;
 
        size_t lpos, rpos;
        string lstr = R"("min":)", rstr = ",";
        lpos = page.find(lstr);
        rpos = page.find(rstr, lpos);
 
        str_dbl = page.substr(lpos + lstr.size(), rpos - lpos - lstr.size());
        cout << str_dbl << endl; //298919.55
 
        //nlohmann::json
        json jdata = json::parse(page);
        jdata = jdata["ranges"];
 
        cout << jdata["min"] << endl; //298919.55
        cout << jdata["min"].get<json::number_float_t>() << endl; //298920
 
        dbl = jdata["min"];
        cout << dbl << endl; //298920
 
        dbl = jdata["min"].get<json::number_float_t>();
        cout << dbl << endl; //298920
 
        
        ifile2.close();
Содержание example1.txt: 298919.55;298919,55;

example1.txt

Содержание example2.txt: данные в json.

example2.txt

Кодировка файлов utf-8.
В другом проекте удалось решить эту проблему вводом данных в консоль, а не чтением из файла, но здесь так не получится.
В сети нашел упоминание об этой проблеме, а так же то что это связано с локалями и from_chars которая "locale-independent" и должна, ее, по существу, решать, хотя я вижу что от смены локали меняется вывод from_chars.
std::setlocale(LC_ALL, "C") тоже пробовал.
Хотелось бы получать корректное преобразование.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.08.2021, 11:31
Ответы с готовыми решениями:

Почему в MSVC++ 2008 компилируется, а в MSVC++ 2010 вылезает много ошибок?
Кстати, перед запуском в 2010 предлагает конвертировать код. Ну а чем эти две студии отличаются, что вызывает большое количество ошибок?

Где можно скачать MSVC 1.0 или MSVC 1.5 ?
Где можно скачать MSVC 1.0 или MSVC 1.5 ?

Переход от MSVC 2017 к MSVC 2019
Добрый день, До сих пор я использовал MSVC 2017 x64, но планирую перейти на компилятор MSVC 2019 x64 в связи с тем, что 2017 не...

4
2736 / 891 / 331
Регистрация: 10.02.2018
Сообщений: 2,113
26.08.2021, 13:24
Цитата Сообщение от S_Vvardenfell Посмотреть сообщение
298919.55;298919,55;
В ваших исходных текстах числа записаны вперемешку, то через точку дробная часть, то через запятую, и вы хотите что бы это всегда читалось как числа с плавающей точкой, так нужно понимать вашу проблему?
0
1 / 1 / 0
Регистрация: 23.03.2020
Сообщений: 3
26.08.2021, 15:08  [ТС]
Добрый день. Запятые поставлены чтобы показать что не работает с любым разделителем.
Видел где-то информацию что в русской локали разделителем является запятая и должно работать корректно, так вот комбинация русской локали и запятой не дала эффекта.

Добавлено через 18 минут
Проблема только на рабочем компе, на домашнем всё конвертируется отлично. Куда смотреть?)

Добавлено через 7 минут
Похоже, нашел проблему. В пустом проекте всё конвертируется корректно без потери чисел после запятой. По-видимому, проблема в какой-то из зависимостей (qumbo, gumboQuery, nlohmann::json, crypto, tinyxml); Можно закрывать тему

Добавлено через 11 минут
Проблема при использовании nlohmann::json для парсинга
0
Just Do It!
 Аватар для XLAT
4211 / 2670 / 655
Регистрация: 23.09.2014
Сообщений: 9,083
Записей в блоге: 3
26.08.2021, 15:17
Лучший ответ Сообщение было отмечено S_Vvardenfell как решение

Решение

Цитата Сообщение от S_Vvardenfell Посмотреть сообщение
cout << dbl << endl; //298920
C++
1
#include <iomanip>
...
C++
71
cout << std::setprecision(12) << dbl << endl;
0
1 / 1 / 0
Регистрация: 23.03.2020
Сообщений: 3
30.08.2021, 12:38  [ТС]
Не подумал что дело может быть только в выводе в консоль. Так просто, что не принял во внимание даже.

Добавлено через 6 минут
Хотя вот не уверен. Скопировал с файла значения, а не ввел в консоль - и снова отлетело всё что после точки, и setprecision не помог

Добавлено через 16 минут
Всё ок) извиняюсь
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.08.2021, 12:38
Помогаю со студенческими работами здесь

std::strtod
Привет. Почему strtod, когда принимает числа меньше единицы переводит их в double, как 0.0? Пример: строка - &quot;0,5&quot;, на выходе -...

Неправильная работа if
Привет! Задали по лабараторки сделать программу, обрабатывающию 2 уровнения. Задание: y=f1 если C, в противном случае y=f2 (сами функции...

Неправильная работа
Почему на неправильно работает? #include&lt;iostream&gt; using namespace std; int main() { int b; for (int i=0; i&lt;=14;...

Неправильная работа БД
Добрый вечер. Проблема такова: Есть вот такой код: private void InitializeDataGridView() { List&lt;string&gt; data =...

Неправильная работа if
import random, os Numbers = while True: comp = random.choice(Numbers) player = input('Введите число от 1 до 5 ') ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Кому нужен AOT?
DevAlt 26.03.2026
Решил сделать простой ланчер Написал заготовку: dotnet new console --aot -o UrlHandler var items = args. Split(":"); var tag = items; var id = items; var executable = args;. . .
Отправка уведомления на почту при изменении наименования справочника
Maks 24.03.2026
Программная отправка письма электронной почты на примере изменения наименования типового справочника "Склады" в конфигурации БП3. Перед реализацией необходимо выполнить настройку системной учетной. . .
модель ЗдравоСохранения 5. Меньше увольнений- больше дохода!
anaschu 24.03.2026
Теперь система здравосохранения уменьшает количество увольнений. 9TO2GP2bpX4 a42b81fb172ffc12ca589c7898261ccb/ https:/ / rutube. ru/ video/ a42b81fb172ffc12ca589c7898261ccb/ Слева синяя линия -. . .
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере нетипового документа выдачи шин для спецтехники с табличной частью, разработанного в конфигурации КА2. Номеклатура. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru