c++ jak sie ustawia separator dziesietny ?

0

Jak to się robi w c++ ?
Jak ustawić w kontekście aplikacji aby wszystkie funkcje float -> string i string -> float używały "KROPKI" a nie przecinka ?
Ideałem było by rozwiązanie niezależne od OS

3

Niezależne od OS-a, ale upierdliwe, jest naklepanie swojego rozwiązania od zera.

Zależne od OS-a, i w sumie też upierdliwe, ale „klasyczne”, jest wykorzystanie std::locale, a konkretnie std::numpunct: https://en.cppreference.com/w/cpp/locale/locale

2

string.replace ',' -> '.'

Używam we wszystkich językach, mając niewiadomą sytuację z locale.
Nieeleganckie, proste jak cepy i skuteczne

1

//edit
zobacz jak podeszli do problemu i zrobili programiści od Excel czy Calc ,
nie bawią się w żadną modyfikację tylko oczekują, że user wprowadzi należyty (odpowiedni) typ

napisz własne rozwiązanie i skorzystaj z wyrażeń regularnych bibliotek regex lub Boost.Regex

przyjmując jako string trzeba przeprowadzić walidację całego ciągu alfanumerycznego, a nie tylko poprzestać na zamianie przecinka na kropkę.
nie jest to kompleksowe rozwiązanie, nie uwzględniam tu np. ujemnych wartości czy notacji naukowej
możesz sobie przetestować wpisując np "adam 6 ,,,,, agata 25" , "To masz 20" , "i3,,,,4...10" itp.

/* Copyright (©) 2022 by OfEl */
#include <iostream>
#include <limits>
#include <cmath>
#include <regex>

using namespace std;

double checked_number_double_regex();
void clear_input();
double aproksymacja(float liczba);

int main()
{
    bool infinity = true;
    double number;
    char decyzja;
    while(infinity)
    {
        cout << "Podaj cyfre/liczbe typu double/float: ";
        number = checked_number_double_regex();
        cout << "Number : " << number << "\n";

        cout << "\n\t\tKontynuowac 't' lub 'T' albo 'y' lub 'Y' := ";
        cin >> decyzja;
        if( (decyzja=='T') || (decyzja=='t') || (decyzja=='Y') || (decyzja=='y') )
        { infinity = true;} else { infinity = false; break; }
        clear_input();
        cout << '\n';
    }
    cout << "Bye!" << endl;
    return 0;
}

double checked_number_double_regex()
{
    string str, str_tmp;
    getline(cin, str_tmp);

    const regex remove_all_sign("([^0-9.,])");
    str_tmp = regex_replace(str_tmp, remove_all_sign, "");
    replace(str_tmp.begin(), str_tmp.end(), ',', '.');

    for( unsigned i = 0; i < str_tmp.length(); ++i )
    {
        if( !( str_tmp[ i ] == '.' && str_tmp[ i + 1 ] == '.' ) )
        {
            str += str_tmp[ i ];
        }
    }

    double liczba = atof(str.c_str());

    while(true)
    {
        if (!liczba)
        {
            cout << "\tWprowadzony znak nie jest cyfra/liczba" << endl;
            cout << "\tProsze podac cyfre/liczbe : ";
            return checked_number_double_regex(); //rekurencja
        }
        else if(liczba)
        {
            break;
        }
    }
    liczba = aproksymacja(liczba);
    return fabs(liczba);
}

double aproksymacja(float liczba)
{
    long long int wynik = fabs(liczba * 1000);
    if (wynik % 10 >= 5) abs(wynik += 10);
    return fabs((wynik / 10) * 0.01);
}
void clear_input()
{
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}

3

Powinno być tak:

std::cout.imbue(std::locale("pl_PL"));

Lub można polegać na systemowych ustawieniach:

std::cout.imbue(std::locale(""));
0

dziękuje za podpowiedzi ! będę musiał poszukać na ten temat i poczytać .

Ja pracuje na Win EN

Ale czasami testuje na Ubuntu PL z takim locale:

LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=pl_PL.UTF-8
LC_TIME=pl_PL.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=pl_PL.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=pl_PL.UTF-8
LC_NAME=pl_PL.UTF-8
LC_ADDRESS=pl_PL.UTF-8
LC_TELEPHONE=pl_PL.UTF-8
LC_MEASUREMENT=pl_PL.UTF-8
LC_IDENTIFICATION=pl_PL.UTF-8
LC_ALL=

jak sprawdzam na Linux na poczatku main() to wszystko zachowuje sie OK (separator to kropka) , w tej samej aplikacji w oknie Qt już widzę wynik z PRZECINKIEM i to mnie tak trochę zastanowiło

1

Jak używasz Qt, to poczytaj to, wraz z linkami z tej strony.

1
Adamek Adam napisał(a):

jak sprawdzam na Linux na poczatku main() to wszystko zachowuje sie OK (separator to kropka) , w tej samej aplikacji w oknie Qt już widzę wynik z PRZECINKIEM i to mnie tak trochę zastanowiło

Trzeba było od tego zacząć.
W Qt domyślnie kontrolki używają systemowego locale.
Zmień locale na C locale https://doc.qt.io/qt-5/qwidget.html#locale-prop i po kłopocie.

Albo:
QLocale Class | Qt Core 5.15.9

void QLocale::setDefault(const QLocale &locale)

Sets the global default locale to locale. These values are used when a QLocale object is constructed with no arguments. If this function is not called, the system's locale is used.

1 użytkowników online, w tym zalogowanych: 0, gości: 1