Преобразование (const char*) var идет не так

Мне нужно преобразовать CString в double в Embedded Visual C++, который поддерживает только старый стиль C++. Я использую следующий код

CString str = "4.5"; double var = atof( (const char*) (LPCTSTR) str )

и результат var=4.0, поэтому я теряю десятичные цифры. Я сделал еще один тест

LPCTSTR str = "4.5"; const char* var = (const char*) str

и снова результат var=4.0 Может ли кто-нибудь помочь мне получить правильный результат?

Вы уверены, что источник (str) действительно указывает на строку, которую вы думаете? Если вы пройдёте код в отладчике, что он вам скажет?

Some programmer dude 09.04.2019 10:20

Это может быть проблема с локализацией. Посмотрите на setlocale(). В некоторых языках (например, в немецком) значения . и , меняются местами. Если активна немецкая локаль, синтаксический анализ "4.0" останавливается на .. (В этом случае "4,5" вернет правильный результат 4.5.)

Scheff's Cat 09.04.2019 10:25
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
106
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

CString не является const char* Чтобы преобразовать CString TCHAR в ASCII, используйте макрос CT2A — это также позволит вам преобразовать строку в UTF8 (или любую другую кодовую страницу Windows):

// Convert using the local code page
CString str(_T("Hello, world!"));
CT2A ascii(str);
TRACE(_T("ASCII: %S\n"), ascii.m_psz);

// Convert to UTF8
CString str(_T("Some Unicode goodness"));
CT2A ascii(str, CP_UTF8);
TRACE(_T("UTF8: %S\n"), ascii.m_psz);

Там макросы являются частью ATL, а не стандартом С++. Прочтите это для получения инструкций по использованию docs.microsoft.com/en-us/previous-versions/87zae4a3(v=vs.140‌​). Скорее всего, вы не включаете заголовки. #include <atldef.h> #include <atlstr.h>

cprogrammer 09.04.2019 11:06

Нет, _wtof нет, только atof

Slav 09.04.2019 11:15

Я не пытался включать atldef.h, так как нашел решение с помощью scanf (см. ответ ниже). Но большое спасибо за помощь.

Slav 09.04.2019 11:21

Последний абзац неверный. Проблема здесь в символе кодирование, а не в конкретных используемых символах. Строка "4.5" кодируется как 34 2E 35 00 (ASCII) и 34 00 2E 00 35 00 00 00 (UTF-16 LE). Когда вы преобразуете строку Unicode в строку ASCII (или ANSI), вы усекаете ее, в результате чего получается строка 34 00. Этот последний фрагмент кода работает только тогда, когда ваш проект настроен на использование кодировки MBCS, чего вы никогда не хотите.

IInspectable 09.04.2019 12:26
Ответ принят как подходящий

Нашел решение с помощью scanf

CString str = "4.5" double var=0.0; _stscanf( str, _T("%lf"), &var );

Это дает правильный результат var=4.5 Спасибо всем за комментарии и помощь.

Проблема здесь в том, что вы лжете компилятору, а компилятор доверяет вам. Используя Embedded Visual C++, я предполагаю, что вы ориентируетесь на Windows CE. Windows CE предоставляет только поверхность Unicode API, поэтому ваш проект, скорее всего, настроен на использование Unicode (кодировка UTF-16 LE).

В этом случае CString заменяется на CStringW, в котором кодовые единицы хранятся как wchar_t. Когда вы делаете (const char*) (LPCTSTR) str, вы переходите от wchar_t const* к char const*. Учитывая ввод, первый байт имеет значение 52 (кодировка ASCII для символа 4). Второй байт имеет значение 0. Это интерпретируется как терминатор строки в стиле C. Другими словами, вы передаете строку "4" своему вызову atof. Естественно, в результате вы получите значение 4.0.

Чтобы исправить код, используйте что-то вроде следующего:

CStringW str = L"4.5";
double var = _wtof( str.GetString() );

_wtof — это специфичное для Microsoft расширение CRT.

Обратите особое внимание на две вещи:

  • В коде используется вариант CString с кодировкой символов явный (CStringW). Всегда четко указывайте типы строк. Это помогает читать ваш код и выявлять ошибки до того, как они произойдут (хотя все эти приведения в стиле C в исходном коде полностью устраняют это).
  • Код вызывает элемент CString:: Жетстринг для получения указателя на неизменяемый буфер. Это также облегчает чтение кода, так как не используется то, что выглядит как приведение в стиле C (но вместо этого используется оператор).

Также рассмотрите возможность определения макроса _CSTRING_DISABLE_NARROW_WIDE_CONVERSION, чтобы предотвратить непреднамеренное преобразование набора символов (например, CString str = "4.5";). Это также помогает вам обнаруживать ошибки на ранней стадии (если только вы не справитесь с этим с помощью приведения типов в стиле C).

К сожалению, в Embedded Visual C++ 4.0 нет типа wchar_t, как нет и метода GetString в этой версии MFC для CString. К тому же вы только критикуете, не давая ответа на вопрос. Так что ваш комментарий не актуален.

Slav 09.04.2019 14:34

Используйте WCHAR, если компилятор не поддерживает wchar_t. Если ваша версия MFC не предоставляет элемент GetString, используйте operator LPCWSTR().

IInspectable 09.04.2019 14:53

Другие вопросы по теме