Toon posts:

[c++] float to char

Pagina: 1
Acties:

Verwijderd

Topicstarter
Als ik een float heb waar de waarde bv. 76.13 is. Dan wil ik een functie maken waar ik een voor een de waardes (ook de punt) terug krijg.
Ik heb helemaal geen flauw idee hoe ik dit moet aanpakken ik heb wel zitten denken om het met bitshifting te doen maar dan moet je eerst een waarde uit de float zien te krijgen.
Hopelijk kan iemand mij helpen.

  • marcusk
  • Registratie: Februari 2001
  • Laatst online: 26-09-2023
eerst de float naar een string omzetten en dan char voor char lezen?

(zie sprintf)

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

sprintf() ?

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

...en dan krijg je dus een array van characters terug die je 1 voor 1 kan uitlezen ;)

om maar even voor een aanvulling te zorgen...

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 11-09 18:38
sprintf() is geen goed idee, zie http://www.gotw.ca/publications/mill19.htm
In summary, here's how snprintf() compares to sprintf():

Standard?
snprintf: Yes: C99 only, but will likely be in C++0x
sprintf: Yes: C90, C++98, C99

Easy to use, good code clarity?
snprintf: Yes
sprintf: Yes

Efficient, no extra allocation?
snprintf: Yes
sprintf: Yes

Length safe?
snprintf: Yes
sprintf: No

Type safe?
snprintf: No
sprintf: No

Usable in template?
snprintf: No
sprintf: No

Guideline: Never use sprintf(). If you decide to use C stdio facilities, always use length-checked calls like snprintf() even if they're only available as a nonstandard extension on your current compiler. There's no drawback, and there's real benefit, to using snprintf() instead.

When I presented this material as part of a talk at Software Development East in Boston this summer [2001], I was shocked to discover that only about ten percent of the class had heard of snprintf(). But one of those who had immediately put up his hand to describe how, on his current project, they'd recently discovered a few buffer-overrun bugs, globally replaced sprintf() with snprintf() throughout the project, and found during testing that not only were those bugs gone but suddenly several other mysterious bugs had also disappeared - bugs that had been reported for years but that the team hadn't been able to diagnose. As I was saying: Never use sprintf().

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

PRINTF!! Oh nee, toch niet.
code:
1
2
3
4
5
6
#include <strstream>

const float PI= 3.14;
std::ostrstream conv;
conv << PI;
std::cout << conv.str() << std::endl;

(En als je een nieuwe library hebt stringstream gebruiken ipv. strstream.)

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:13
Wat is het voordeel van die streams boven sprintf (of de STL variant daarvan)? Met jou methode moet je een tijdelijk object instantiëren en opruimen en heb je meer regels nodig, wat de leesbaarheid niet ten goede komt. Wat krijg je daar voor terug?

PS. Wanneer leren mensen nou eens om string te schrijven als ze string bedoelen (en dus geen char)?!

Verwijderd

Op donderdag 07 maart 2002 11:56 schreef Soultaker het volgende:
Wat is het voordeel van die streams boven sprintf (of de STL variant daarvan)? Met jou methode moet je een tijdelijk object instantiëren en opruimen en heb je meer regels nodig, wat de leesbaarheid niet ten goede komt. Wat krijg je daar voor terug?
En snprintf heeft geen tijdelijk object nodig? Hoe zit het dan met dat char-array waarin je met die snprintf schrijft? Het grote voordeel van stringstreams is dat je geen rekening hoeft te houden met buffergroottes, bufferoverflows zijn impliciet onmogelijk (bij snprintf zijn ze expliciet, geef een te grote n op en je bent dood).

Daarnaast zijn << operators zeer leesbaar, als je de streams-library maar gebruikt. Hoe meer code je leest en zelf schrijft die gebruik maakt van streams, hoe leesbaarder het wordt. (Daarnaast zijn die %i %s %f format-strings ook niet al te leesbaar, het is echt een kwestie van gewenning.)

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:13
Op donderdag 07 maart 2002 12:08 schreef mietje het volgende:
En snprintf heeft geen tijdelijk object nodig? Hoe zit het dan met dat char-array waarin je met die snprintf schrijft? Het grote voordeel van stringstreams is dat je geen rekening hoeft te houden met buffergroottes, bufferoverflows zijn impliciet onmogelijk (bij snprintf zijn ze expliciet, geef een te grote n op en je bent dood).
Een printf-functie heeft inderdaad geen tijdelijk object nodig. Als ik naar de standard output schrijf, zoals jij doet, kan ik gewoon printf("%f",0.1"); doen. Daar hoef ik niets voor te alloceren of instantiëren.

Als ik de string op wil slaan, moet ik inderdaad ruimte alloceren voor de string. Maar dat moet jij dan ook nog doen! Jou stream object levert immers ook een nieuwe string op. In beide scenario's moet je dus een extra object alloceren.

Verder doen imho streamnotaties enigszins afbreuk aan de leesbaarheid van de code, omdat het steeds onduidelijk is met welke types er wordt gewerkt. Als het er niet direct boven had gestaan, had ik niet kunnen zien dat PI een float is, wat wel direct uit de format specifier blijkt. (Niet geheel volgens de standaard maar wel erg handig waarschuwt de GNU compiler als je andere argumenten in een format stopt dan je in je format string hebt aangekondigt).

edit:
Wat is er mis met m'n quote tags? Ah, ik zie 't al =)

Verwijderd

Op donderdag 07 maart 2002 12:18 schreef Soultaker het volgende:
Een printf-functie heeft inderdaad geen tijdelijk object nodig. Als ik naar de standard output schrijf, zoals jij doet, kan ik gewoon printf("%f",0.1"); doen. Daar hoef ik niets voor te alloceren of instantiëren.
Wat is het verschil met std::cout << 0.1? Wat alloceer ik meer?
Als ik de string op wil slaan, moet ik inderdaad ruimte alloceren voor de string. Maar dat moet jij dan ook nog doen! Jou stream object levert immers ook een nieuwe string op. In beide scenario's moet je dus een extra object alloceren.
Exact, het maakt dus in principe niets uit, er wordt een object meer geinstantieerd (de stringstream die als wrapper rond de buffer dient). Als je niet van het instantieeren van tijdelijke wrapper-objecten houdt, is OOP niet de juiste programmeertechniek, je kunt dan beter teruggaan naar structured programming...
Verder doen imho streamnotaties enigszins afbreuk aan de leesbaarheid van de code, omdat het steeds onduidelijk is met welke types er wordt gewerkt. Als het er niet direct boven had gestaan, had ik niet kunnen zien dat PI een float is, wat wel direct uit de format specifier blijkt.
Dit is dus juist een enorm nadeel van de printf famillie, ze is niet typesafe! Verander je in je code van een float in een double maar vergeet de format-string aan te passen, dan levert printf garbage. De stream zal nooit garbage leveren, hoogstens een compiler-error.
(Niet geheel volgens de standaard maar wel erg handig waarschuwt de GNU compiler als je andere argumenten in een format stopt dan je in je format string hebt aangekondigt).
Dat is dus een "evil hack" ;) om te proberen toch iets van typesafety in de printf familie te krijgen.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 15:13
Op donderdag 07 maart 2002 12:28 schreef mietje het volgende:
Wat is het verschil met std::cout << 0.1? Wat alloceer ik meer?
In dit geval niets, natuurlijk. In het eerste voorbeeld gebruikte je echter een converteer-stream, die vervolgens (met conv.str()) een string-object opleverde (neem ik aan). Als je dus je float met deze methode om wil zetten in een string, ontkom je er niet aan dat je twee objecten instantieert. Maar dat zeg je hier eigenlijk zelf ook al:
Exact, het maakt dus in principe niets uit, er wordt een object meer geinstantieerd (de stringstream die als wrapper rond de buffer dient). Als je niet van het instantieeren van tijdelijke wrapper-objecten houdt, is OOP niet de juiste programmeertechniek, je kunt dan beter teruggaan naar structured programming...
Ik zie OOP meer als een techniek om applicaties op macro-nivo helder te houden. Het voordeel van C++ is nu juist dat je in de feitelijke implementatie van methoden gebruik kunt maken van alle imperatieve en functionele structuren die in C ook al mogelijk waren.
Dit is dus juist een enorm nadeel van de printf famillie, ze is niet typesafe! Verander je in je code van een float in een double maar vergeet de format-string aan te passen, dan levert printf garbage. De stream zal nooit garbage leveren, hoogstens een compiler-error.
Ben ik met je eens. Ik probeer in de praktijk printf formatstrings zo straightforward mogelijk te houden (door eventueel meerdere printf statements achter elkaar te zetten) zodat je eenvoudigweg kan zien of iets klopt. Ook de compiler met de 'evil hack' (ook hier ben ik het met je eens) helpt erg mee.

Het controleren van het type en het aantal van variabele argumenten is in zijn algemeenheid een probleem in C/C++. Valt helaas vrij weinig aan te doen, aangezien C/C++ geen runtime typen kent.

Verwijderd

Op donderdag 07 maart 2002 15:53 schreef Soultaker het volgende:
In dit geval niets, natuurlijk. In het eerste voorbeeld gebruikte je echter een converteer-stream, die vervolgens (met conv.str()) een string-object opleverde (neem ik aan).
Daar gaat het dus fout ;) conv.str() levert gewoon een blote char* in de buffer, en lockt die buffer. Er wordt dus geen extra std::string (ofzo) aangemaakt.

De stream-library is in wezen erg efficient ontworpen, dat je (in windows!) grote, trage executables krijgt bij het gebruik van streams ligt meer aan de compiler en aan de implementatie van de libs dan aan het design van de streams.
Ik zie OOP meer als een techniek om applicaties op macro-nivo helder te houden. Het voordeel van C++ is nu juist dat je in de feitelijke implementatie van methoden gebruik kunt maken van alle imperatieve en functionele structuren die in C ook al mogelijk waren.
Dan moet je er ook bij vertellen dat elk voordeel ze nadeel heb. :) Als je teveel "C-style" programmeert in grote projecten, krijg je ook exact dezelfde problemen als in grote C projecten. Hoe "losser" je programmeert, hoe meer tijd het debuggen naderhand gaat kosten, vooral als je in een groot team werkt (om van flames tijdens code-audits nog maar te zwijgen).
Het controleren van het type en het aantal van variabele argumenten is in zijn algemeenheid een probleem in C/C++. Valt helaas vrij weinig aan te doen, aangezien C/C++ geen runtime typen kent.
C kent geen rtti, bij moderne C++ compilers is rtti optioneel (kost veel overhead).
Pagina: 1