Konwersja float na const char*

0

W jaki sposób mogę przekonwertować zmienną float na const char* ?
Zrobiłem coś takiego:

float var = 12.34
(std::to_string(var)).c_str()

i to nawet działa, tylko że w wyniku tej operacji dostaję 21.3400000, a potrzebuję tylko dwie cyfry po przecinku.

1

Możesz spróbować przez stringstream:

ostringstream ss;
ss << setprecision(3) << f;
const char* str = ss.str().c_str();

Jakoś tak, napisałem z palca, musisz sprawdzić czy działa.

0

Powyższa metoda niestety nie wyświetla mi żadnego napisu. Spróbowałem jeszcze zrobić tak:

    const char* val = (std::to_string(data.dx.vol)).c_str();
    char valC[6];

    for (int i = 0; i < 5; i++) {
        valC[0] = *(val + i);
    }

i valC przekazać do funkcji ale niestety też nie działa. Natomiast jeżeli napiszę valC[6] = "12.34" i to przekażę jako parametr do funkcji to się wyświetla. Musi więc być to wina konwersji i prawdopodobnie jak twonek wyżej wspomniał pewnie coś z tym wskaźnikiem jest nie tak.

1
valC[0] = *(val + i);

skoro do tej samej komórki valC[0] zapisujesz kolejne literki, to jak ma działać?

Ale ta metoda jest ułomna z definicji. c_str() się używa od razu w wywołaniu funkcji, bo tylko wtedy masz gwarancję poprawności danych.

3

@mlp jeżeli dobrze zrozumiałem, że stringa potrzebujesz przekazać do jakiejś funkcji, i chcesz tylko pierwsze pięć znakó

void yourFunc(const char *strFloat) { ... }

const auto str  = std::to_string(data.dx.vol).substr(0,5);

yourFunc(str.c_str());
1

Miks pierwszej i ostatniej wersji:

#include <iostream>
#include <sstream>
#include <iomanip>

using namespace std;

void myFunc(const char *strFloat) {
    cout << "myFunc: ";
    while(*strFloat) {
        cout << *(strFloat++);
    }
    cout << endl;
}

int main() {
  const float var = 12.34;  
  ostringstream ss;
  ss << std::fixed << setprecision(2) << var;
  myFunc(ss.str().c_str());
  return 0;
}

http://ideone.com/ocOgkL

6

Ale kombinujecie.

char buf[32];
sprintf(buf, "%.2f", 12.34);

ewentualnie

std::stringstream foo;
foo << std::fixed << std::setprecision(2) << 12.34;
std::string out;
foo >> out;

Jak dla mnie metoda z format stringiem jest tutaj czytelniejsza, strzelałbym też, że szybsza.

A sposób zaprezentowany w innych miejscach, t.j. wywoływanie .c_str() na obiekcie tymczasowym jest szalenie zdradliwy. Czas życia danych wskazywanych przez ten wskaźnik jest równy czasowi życia obiektu tymczasowego, więc nawet jeśli @several i @vpiotr zastosowali go poprawnie, to bardzo bym odradzał jego stosowanie w praktyce. Szczególnie przez mniej doświadczonych programistów.

0
mlp99 napisał(a):

W jaki sposób mogę przekonwertować zmienną float na const char* ?
Zrobiłem coś takiego:

float var = 12.34
(std::to_string(var)).c_str()

i to nawet działa, tylko że w wyniku tej operacji dostaję 21.3400000, a potrzebuję tylko dwie cyfry po przecinku.

liczba zmiennoprzecinkowa nie ma takiej czy innej ilości cyfr po przecinku. Jest po prostu liczbą, w rzeczywistości binarną. Wypadało by odróżniać liczbę od jej widzialnego formatowania na 'outpucie'.

Co więcej, niektóre liczby nie istnieją (problem reprezentacji).
Przykładowa float 12.34 też nie istnieje. jej "bardziej prawdziwa" wartość to 12.3400002 (może jakaś inna platforma wyliczy przykładowo 12.339997).

Niestety wiedza o zmiennym przecinku kiedyś tak podstawowa, jakoś zanikła wśród mas programistycznych. To czasem może skopać pewną część ciała. Jeszcze o ograniczonej dokładności ktoś by sobie coś przypomniał, o problemie reprezentacji nieliczni. Zarówno biblioteki, a zwłaszcza IDE robią MSZ krzywdę jak prezentują liczby zbyt "przyjaźnie" (a fałszywe)

Użyta w innym miejscu liczba to 21.3400002.

Zgadzam się z kolegami, którzy przestrzegają przed c_str() itd, te fragmenty są pełne UB/ błedów... ale mi to dodatkowo pachnie jakimś problemem XY

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