LINUX.ORG.RU

Как настроить QtCreator на работу sscanf с разделителем точка, а не с запятая в строке?

 


0

1

Народ, подскажите, пожалуйста как решить проблему! Если в строке разделить точка, а не запятая, то в sscanf данные считываются не верно из-за использования QCoreApplication!

Код примера: #include <QCoreApplication> #include <stdio.h> #include <stdlib.h> #include <string> using namespace std;

int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); string str1 =" -18.6622 342.5735 ", str2 = " -18,6622 342,5735 "; double f,ff; sscanf(str1.c_str(),«%lf %lf»,&f, &ff); //не верно sscanf(str2.c_str(),«%lf %lf»,&f, &ff); //верный рез-т printf(«%lf %lf\n», f, ff); return a.exec(); }

Работаю в OS Linux QtCreator2.6.2 (64bit), языки русский/английский.QCoreApplication нужен в реальном проекте для работы! Использовать каждый раз setlocale(LC_ALL, «C»); перед sscanf или переписывать коды старых библиотек не хочется!


поменять локаль на какую-нибудь страну, которая использует точки вместо запятых пробовал?

из-за использования QCoreApplication

если в землю влетел метеорит, во всем виноваты коммунисты)

stevejobs ★★★★☆
()

инкрементирую ImperialDwarf

не хочешь бросить сишные замашки и читать консоль по-плюсовому? может тогда и ногу не отстрелишь себе

QTextStream qtin(stdin); 
QString line = qtin.readLine();  
EugeneBas ★★
()
Ответ на: комментарий от ImperialDwarf
#include <QCoreApplication>

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
using namespace std;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    string str1 =" -18.6622 342.5735 ";
    string str2 = " -18,6622 342,5735 ";

    long double f;
    long double ff;

    sscanf(str1.c_str(),"%Lf %Lf",&f, &ff); //не верно
    std::cout << f << std::endl << ff << std::endl;

    sscanf(str2.c_str(),"%Lf %Lf",&f, &ff); //верно
    std::cout << f << std::endl << ff << std::endl;

    fgetchar();
}

странность вероятно в том, что на выходе будет:

-18.6622
342.5735
-18 
342,5735

(второй раз отрезало дробную часть)

UPD: если забить на дробную часть, то всё работает отлично. Т.е. там, где у ТСа написано «не верно» у меня всё ОК

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)
    double f;
    QString str1("-18,6622 342,5735");
    QStringList strList = str1.split(' ');
    for(int i = 0; i < strList.length(); i++)
    {
        if(strList.at(i).contains(','))
        {
            QStringList doubleList = strList.at(i).split(',');
            if(doubleList.at(0).toDouble() > 0)
                f = doubleList.at(0).toDouble() + (doubleList.at(1).toFloat() / pow(10, doubleList.at(1).length()));
            else
                f = doubleList.at(0).toDouble() - (doubleList.at(1).toFloat() / pow(10, doubleList.at(1).length()));
        } else {
            f = strList.at(i).toDouble();
        }
    }
ImperialDwarf
()
Ответ на: комментарий от stevejobs

Ссылку я кинул для ознакомления) А код и так читается, хоть и вырвиглазно)

ImperialDwarf
()
Ответ на: комментарий от ImperialDwarf

с довольно большим функционалом

Из очень многомерного пространства?

ТС,

переписывать коды старых библиотек не хочется!

ты бы и не осилил

Использовать каждый раз setlocale(LC_ALL, «C»);

Любую, которая имеет соответствующий десятичный разделитель, и не только перед строкой, но и вернуть после строки на месте. Это если ты пишешь на Си. А ты пишешь на си++, вот и юзай, будь добр, хотя бы stl: https://dl.dropboxusercontent.com/u/12869350/snapshot81.png

cdshines ★★★★★
()
Ответ на: комментарий от cdshines

Это я один ридер завел, а если у тебя много строк и такого, и такого формата, чтоб не переключать локали, можно завести пару с разными локалями и читать одни значения одним ридером, а другие - другим.

cdshines ★★★★★
()

трындец, может перед тем, как брать Qt, стоит выучить хотя Си, не то чтобы С++?

alex_custov ★★★★★
()
Ответ на: комментарий от ImperialDwarf
double f;
QString str1("-18,6622 342,5735");
QStringList strList = str1.split(' ');
foreach(QString line, strList) {
  line.replace(",",".");
  f = line.toDouble();
}
anonymous
()
Ответ на: комментарий от anonymous

После того как отпостил предыдущей код тоже подумал об этом варианте, но пора уже было идти домой с работы)

ImperialDwarf
()

топик не читал, но LC_NUMERIC=C

annulen ★★★★★
()

Использовать каждый раз setlocale(LC_ALL, «C»); перед sscanf ... не хочется!

man setlocale

theNamelessOne ★★★★★
()
Ответ на: комментарий от stevejobs

Всем спасибо, даже тем..... кто вместо ответа был излишне остроумным ((

Всем спасибо, но почти все мимо цели отвечали! Видимо, не внимательно читали мои пояснения, там сказано - даю пример для демонстрации проблемки! Разумеется это не код из реальной проги (реальны только числа :-))) ! Если мне нужны значения типа double, то про какое отбрасывание дробной части может идти речь?!! Реальное приложение у меня не консольное, хотя Qt используются только для создания пользовательского интерфейса, а все старые библиотеки написаны на Си и в них QString не используется! Разумеется у QString таких проблем нет! Про использование cout альтернатива чтения строк известная, но мне хотелось понять - почему идет переключение на русский разделитель разрядов, если использовать QtApplication и т.п. Хотя,например, QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); не решает проблему!

Решение лежало на поверхности и нашлось само методом «тыка» setlocale(LC_ALL, «C»); в мain.cpp, тогда все подключаемые *.cpp отрабатывают верно в sscanf!

Vita
() автор топика

Ты, наверное, читал каким-то альтернативным способом. Например, через бинокль. Читай САМОЕ ПЕРВОЕ сообщение:

поменять локаль на какую-нибудь страну, которая использует точки вместо запятых пробовал?

твое setlocale(LC_ALL, «C»); именно это и делает.

Если мне нужны значения типа double, то про какое отбрасывание дробной части может идти речь?!!

ты это у компилятора спроси, у меня он во втором случае отбрасывает дробную часть при использовании double

cout альтернатива чтения строк известная

cout - это поток вывода, что какбе понятно по слову out в нем. А cout я написал, потому что лень писать принтф. На результат это вообще никак не влияет.

stevejobs ★★★★☆
()
Последнее исправление: stevejobs (всего исправлений: 1)

Вы что-то принципиально делаете не так. В вашей системе (программе) какая используется локаль? Русская? Тогда, ваш код отработывает абсолютно верно: согласно принятым в России стандартам, десятичным разделителем является именно запятая, а вовсе не точка. Если же вы желаете использовать в вашей программе английскую локаль, то достаточно использовать setlocale() один раз во время инициализации программы и более к этому не возвращаться. Вовсе не обязательно при этом использовать именно С локаль, можно использовать любую другую англоязычную.

Если же вы хотите, чтобы ваша программа воспринимала и точку и запятую в качестве разделителей, то такое поведение заведомо ошибочно, т.к. точка используется в качестве разделителя групп разрядов в русской локали, а запятая - в английской. Поэтому, использование обоих этих знаков пунктуации в качестве десятичного разделителя может вводить пользователя в заблуждение.

Ещё большей глупостью будет использование в качестве разделителя, без особенных мотивов, в коде то точку, то запятую, по очевидным причинам.

next_time ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.