[C++] Hier word ik moedeloos van!! int naar char

Pagina: 1
Acties:
  • 247 views sinds 30-01-2008
  • Reageer

  • active2
  • Registratie: Juni 2001
  • Laatst online: 17-07 21:56

active2

Google is your friend

Topicstarter
Ik wil alleen het volgende:

De int waarde 100 naar de char waarde "100" en niet de ascii waarde van het getal 100.

Ik heb van alles geprobeerd maar nou weet ik het niet meer. :?:?:?

Voor ascii to int heb je de functie atoi --> goeie functie maar andersom lukt dus echt niet.

[os=linux]

Google, Het mirakel van de 21e eeuw!!!!


  • Varienaja
  • Registratie: Februari 2001
  • Laatst online: 14-06-2025

Varienaja

Wie dit leest is gek.

a to i, maar je wilt andersom: i to a?

Siditamentis astuentis pactum.


  • Aaargh!
  • Registratie: Januari 2000
  • Laatst online: 29-08 14:29

Aaargh!

Bow for me for I am prutser

sprintf

edit: veiliger is: snprintf

Those who do not understand Unix are condemned to reinvent it, poorly.


  • Feyd-Rautha
  • Registratie: November 2001
  • Laatst online: 02-08-2025
De functie itoa bestaat ook dacht ik zo :)

Maar, (ik heb ook maar een beperkte kennis c++), kun je het niet zo oplossen:
code:
1
(char)iGetal;

I must not fear. Fear is the mind-killer. Fear is the little-death that brings total obliteration. I will face my fear. I will permit it to pass over me and through me. Where the fear has gone there will be nothing. Only I will remain.


  • Aaargh!
  • Registratie: Januari 2000
  • Laatst online: 29-08 14:29

Aaargh!

Bow for me for I am prutser

Op donderdag 25 juli 2002 22:15 schreef -Avalanche- het volgende:
De functie itoa bestaat ook dacht ik zo :)

Maar, (ik heb ook maar een beperkte kennis c++), kun je het niet zo oplossen:
code:
1
(char)iGetal;
Daarmee zet je het getal "100" om in een ascii char met ascii waarde 100 , dat wil hij nou net niet.

Those who do not understand Unix are condemned to reinvent it, poorly.


  • active2
  • Registratie: Juni 2001
  • Laatst online: 17-07 21:56

active2

Google is your friend

Topicstarter
Op donderdag 25 juli 2002 22:15 schreef Aaargh! het volgende:
sprintf

edit: veiliger is: snprintf
Dat is dus de verkeerde kant op.

Van char "100" naar int 100.

Google, Het mirakel van de 21e eeuw!!!!


  • Ghost(NL)
  • Registratie: December 2000
  • Niet online
Zoals al eerder aangehaald:

char *_itoa( int value, char *string, int radix );

Dat is wat je zoekt :)

i5-12600K PRIME Z690M-PLUS D4 64GB 980 Pro M.2 1TB  MBA M1 13" 8GB 256GB (Late '20)


Verwijderd

Op donderdag 25 juli 2002 22:13 schreef active2 het volgende:
De int waarde 100 naar de char waarde "100"
Op donderdag 25 juli 2002 22:27 schreef active2 het volgende:
Van char "100" naar int 100.
Wat wil je nou :?.

  • active2
  • Registratie: Juni 2001
  • Laatst online: 17-07 21:56

active2

Google is your friend

Topicstarter
Op donderdag 25 juli 2002 22:31 schreef ghostrdr01 het volgende:
Zoals al eerder aangehaald:

char *_itoa( int value, char *string, int radix );

Dat is wat je zoekt :)
In welke header file staat die dan?

Google, Het mirakel van de 21e eeuw!!!!


  • Ghost(NL)
  • Registratie: December 2000
  • Niet online
Ja eh moet ik hier dan serieus antwoord op geven ? Mag toch aannemen dat je weet hoe je help werkt :)

Anywayz Help, index en dan _itoa en dan vertelt je IDE-help wel in welke header hij staat en anders doe je ff een find in files op de include directory van je IDE.

i5-12600K PRIME Z690M-PLUS D4 64GB 980 Pro M.2 1TB  MBA M1 13" 8GB 256GB (Late '20)


  • active2
  • Registratie: Juni 2001
  • Laatst online: 17-07 21:56

active2

Google is your friend

Topicstarter
Op donderdag 25 juli 2002 22:36 schreef ghostrdr01 het volgende:
Ja eh moet ik hier dan serieus antwoord op geven ? Mag toch aannemen dat je weet hoe je help werkt :)

Anywayz Help, index en dan _itoa en dan vertelt je IDE-help wel in welke header hij staat en anders doe je ff een find in files op de include directory van je IDE.
[os=linux] en compiler is g++

Google, Het mirakel van de 21e eeuw!!!!


Verwijderd

in C (maar dat kan een C++ compiler ook wel :) ) :

char theBuffer[4];
sprintf( theBuffer, "%d", 100 );

of

char theBuffer[4];
itoa( 100, theBuffer, 10 ); /* 10 is je basis (10-delig talstelsel hier) */

in C++ kun je ook gebruik maken van "output string streams" :

#include <sstream>
using namespace std;
...
ostringstream theStringStream;
theStringStream << 100;

// vanaf hier kan je mbv theStringStream.str() een string opvragen waarmee je whatever kan doen ...

cout << "Je getal als een string : " << theStringStream.str() << endl;

Er zullen nog wel manieren zijn...
Desnoods doe je zelf ff snel de conversie enzo, bvb door steeds de rest na deling van 10 te nemen en al die digits in een char te gieten en aan elkaar te plakken... maar inderdaad, waarom het wiel opnieuw uitvinden ? :P

[edit]
sorry : itoa staat in stdlib.h en sprintf staat in stdio.h maar ik ging er ff van uit dat je dat wel zou weten ;)

  • Ghost(NL)
  • Registratie: December 2000
  • Niet online
Op donderdag 25 juli 2002 22:31 schreef Sneechy het volgende:

[..]


[..]

Wat wil je nou :?.
Hij wil de integer waarde in een stringetje zodat je hem bv in een grote string kan douwen, zoiets van ik ben 5 jaar :)
waarbij je dus kan doen strcpy(var,"ik ben "); strcat(var, leeftijd); strcat(var, " jaar"); oid

i5-12600K PRIME Z690M-PLUS D4 64GB 980 Pro M.2 1TB  MBA M1 13" 8GB 256GB (Late '20)


  • Aaargh!
  • Registratie: Januari 2000
  • Laatst online: 29-08 14:29

Aaargh!

Bow for me for I am prutser

Op donderdag 25 juli 2002 22:27 schreef active2 het volgende:

[..]

Dat is dus de verkeerde kant op.

Van char "100" naar int 100.
Wat wil je nut, van een int naar een char* of van een char naar een int. aangezien je zelf al met atoi kwam (char to int) nam ik aan dat je snprintf wilde (int to char)

Those who do not understand Unix are condemned to reinvent it, poorly.


  • Ghost(NL)
  • Registratie: December 2000
  • Niet online
Op donderdag 25 juli 2002 22:38 schreef _piranha_ het volgende:
in C (maar dat kan een C++ compiler ook wel :) ) :

char theBuffer[4];
sprintf( theBuffer, "%d", 100 );

of

char theBuffer[4];
itoa( 100, theBuffer, 10 ); /* 10 is je basis (10-delig talstelsel hier) */

in C++ kun je ook gebruik maken van "output string streams" :

#include <sstream>
using namespace std;
...
ostringstream theStringStream;
theStringStream << 100;

// vanaf hier kan je mbv theStringStream.str() een string opvragen waarmee je whatever kan doen ...

cout << "Je getal als een string : " << theStringStream.str() << endl;

Er zullen nog wel manieren zijn...
Desnoods doe je zelf ff snel de conversie enzo, bvb door steeds de rest na deling van 10 te nemen en al die digits in een char te gieten en aan elkaar te plakken... maar inderdaad, waarom het wiel opnieuw uitvinden ? :P
Dit kan idd ook prima of je doet

strstream str;
int leeftijd = 5;
char message[100];
str << "Ik ben " << leeftijd << " jaar";

str >> message;

cout << message << endl;

i5-12600K PRIME Z690M-PLUS D4 64GB 980 Pro M.2 1TB  MBA M1 13" 8GB 256GB (Late '20)


  • Ghost(NL)
  • Registratie: December 2000
  • Niet online
Op donderdag 25 juli 2002 22:38 schreef active2 het volgende:

[..]

[os=linux] en compiler is g++
In mijn IDE is het stdlib.h

i5-12600K PRIME Z690M-PLUS D4 64GB 980 Pro M.2 1TB  MBA M1 13" 8GB 256GB (Late '20)


Verwijderd

Op donderdag 25 juli 2002 22:41 schreef ghostrdr01 het volgende:
Dit kan idd ook prima of je doet

strstream str;
int leeftijd = 5;
char message[100];
str << "Ik ben " << leeftijd << " jaar";

str >> message;

cout << message << endl;
Inderdaad, mogelijkheden zat gewoon ! :) :P

  • active2
  • Registratie: Juni 2001
  • Laatst online: 17-07 21:56

active2

Google is your friend

Topicstarter
Op donderdag 25 juli 2002 22:39 schreef Aaargh! het volgende:

[..]

Wat wil je nut, van een int naar een char* of van een char naar een int. aangezien je zelf al met atoi kwam (char to int) nam ik aan dat je snprintf wilde (int to char)
denk denk denk denk

atoi --> char naar int
Die snprintf is een leuke functie nu even opzoeken hoe dat ding precies werkt. Waar kan ik vinden hoe dat precies werkt? Uit die header file word je niet veel wijs.

Google, Het mirakel van de 21e eeuw!!!!


  • Aaargh!
  • Registratie: Januari 2000
  • Laatst online: 29-08 14:29

Aaargh!

Bow for me for I am prutser

Op donderdag 25 juli 2002 22:45 schreef active2 het volgende:
Die snprintf is een leuke functie nu even opzoeken hoe dat ding precies werkt. Waar kan ik vinden hoe dat precies werkt? Uit die header file word je niet veel wijs.
man snprintf :?

Those who do not understand Unix are condemned to reinvent it, poorly.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op donderdag 25 juli 2002 22:31 schreef ghostrdr01 het volgende:
Zoals al eerder aangehaald:

char *_itoa( int value, char *string, int radix );

Dat is wat je zoekt :)
De _ aan het begin is een redelijke hint dat het een MS-only extensie is. snprintf() in C, of std::ostringstream in C++ zijn de standaard methoden, boost::lexical_cast<std::string> werkt ook

En verder wil je in C++ std::string gebruiken ipv char*

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


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Algemene oplossing:
code:
1
2
3
4
5
6
7
8
#include &lt;sstream&gt;

template &lt;class T&gt;
std::string toString(const T&amp; i) {
   std::ostringstream sstr;
   sstr &lt;&lt; i;
   return sstr.str();
}

  • Boy
  • Registratie: November 2001
  • Laatst online: 14:32

Boy

www.byoscoop.nl

je wilt toch niet zeggen dat hier zo een lange thread over ontstaat??

ik gebruik daarvoor altijd itoa

int i = 5; //integer die je wilt converteren
char s // hier wil je 'm ingooien

itoa(i, &s, 10); //10 betekend decimaal stelsel

Naar de bioscoop? => gebruik de app op Byoscoop.nl


  • Grum
  • Registratie: Juni 2001
  • Niet online
En zoals je ziet was dit al gezegd en doe jij dus met je post een bijzonder goede bijdrage aan deze in jouw ogen al te lange thread ...

Vervolgens was het probleem dat de topicstarter niet wist in welke headerfiles ie et kon vinden (ff zoeken had dat opgelost maar ok :D)

p0m p0m ;)

  • Boy
  • Registratie: November 2001
  • Laatst online: 14:32

Boy

www.byoscoop.nl

ok |:( excuses...laat geworden gisteren, vroeg op, zit dus nog half te :Z

Naar de bioscoop? => gebruik de app op Byoscoop.nl


  • active2
  • Registratie: Juni 2001
  • Laatst online: 17-07 21:56

active2

Google is your friend

Topicstarter
Op vrijdag 26 juli 2002 10:45 schreef Boy het volgende:
je wilt toch niet zeggen dat hier zo een lange thread over ontstaat??

ik gebruik daarvoor altijd itoa

int i = 5; //integer die je wilt converteren
char s // hier wil je 'm ingooien

itoa(i, &s, 10); //10 betekend decimaal stelsel
Het probleem is dat jullie de borland IDE gebruiken enzo.. Maar ik programmeer in linux met g++ en dan heb je toch andere functies maar goed in elk geval bedankt ik ben enorm geholpen. :)

Google, Het mirakel van de 21e eeuw!!!!


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Op vrijdag 26 juli 2002 10:45 schreef Boy het volgende:
je wilt toch niet zeggen dat hier zo een lange thread over ontstaat??
En blijkbaar kwam er nog steeds niet iemand met de string stream gebruikende template functie aan. Wat toch echt wel de C++ standaard is voor dit (probleem) 8-)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 26 juli 2002 10:45 schreef Boy het volgende:
je wilt toch niet zeggen dat hier zo een lange thread over ontstaat??

ik gebruik daarvoor altijd itoa

int i = 5; //integer die je wilt converteren
char s // hier wil je 'm ingooien

itoa(i, &s, 10); //10 betekend decimaal stelsel
Crash, burn, get fired.

itoa schrijft naar een array van chars; s is een "array" met lengte 1. Daar kun je dus net een \0 in krijgen, maar "100" is 4 karakters. Weg stack. snprintf had't ondekt, std::stringstream heeft het probleem niet.

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

Mja, elk zelfrespecterende string class heeft een 'Format' achtige method, en anders kies je voor een string class die er een heeft.

En voor de 7/8 bitters onder ons die alleen ascii willen, is er altijd sprintf, wel de juiste grootte in je buffertje alloceren :)

Voor de allergrootste bitnaaiers is er natuurlijk de eigengeschreven routine die een getal omzet van talstelsel A naar talstelsel B, die kan worden omgebakken naar een waarde in talstelsel A naar een ascii representatie ervan.

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 26 juli 2002 12:58 schreef Otis het volgende:
Mja, elk zelfrespecterende string class heeft een 'Format' achtige method, en anders kies je voor een string class die er een heeft.
Dat is geen goed OO design. Een string is geen formatter.
Als je nou zegt dat elke zelfrespecterende string class een bijpassende formatter class heeft, dan geef ik je helemaal gelijk.
De reden hiervoor is dat formatting rekening moet houden met een a priori onbekend aantal UDTs. Kijk maar naar de std:: aanpak. Als je al die formatting data permanent wil meeslepen met elke string, in plaats van alleen voor die strings die je format en alleen gedurende het formatten, dan wordt de overhead van je string class aanmerkelijk groter.

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


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 26 juli 2002 12:58 schreef Otis het volgende:
En voor de 7/8 bitters onder ons die alleen ascii willen, is er altijd sprintf, wel de juiste grootte in je buffertje alloceren :)
Ok, uitdaging: Gegeven INT_MAX en consorten, hoeveel chars heb je nodig zodat je een int zeker kunt printen?

Oftewel, wat is xxx in termen van INT_MAX e.d. in
code:
1
2
3
4
5
void foo( int i )
{
  char buf[ xxx ];
  sprintf( &amp;x, &quot;%d&quot;, i );
}

't moet het natuurlijk wel op m'n 64 bit doos doen, maar op m'n DOS doos geen overbodige chars gebruiken.

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

Een uitdaging :)
code:
1
2
3
4
5
6
7
#define xxx (((int)log10(INT_MAX)) + 3)
/* + 1 om logaritme op te plussen naar integere macht van 10
 * + 1 voor het evt. minteken
 * + 1 voor terminating '\0'
 * --- =
 * + 3
 */

Overigens is je foo() erg brak ;)

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Op vrijdag 26 juli 2002 12:58 schreef Otis het volgende:
Mja, elk zelfrespecterende string class heeft een 'Format' achtige method, en anders kies je voor een string class die er een heeft.

En voor de 7/8 bitters onder ons die alleen ascii willen, is er altijd sprintf, wel de juiste grootte in je buffertje alloceren :)
Als je String class zelf formatting doet, wordt het heel lastig om (een vorm van) Locales te gebruiken. Het is erg interessant om de C++ stream classes is helemaal door te gaan, en uit te zoeken op welk punt er nou uiteindelijk een character wordt geschreven. Petje af voor degene die dit ontworpen hebben hoor!

Als je alleen ascii wilt kan je gewoon std::basic_ostringstream<char> gebruiken. Anders wchar. (char is per definitie 1 byte, dit hoeven echter geen 8 bits te zijn ;) )

Verwijderd

Op vrijdag 26 juli 2002 13:18 schreef MSalters het volgende:
[..]
Dat is geen goed OO design. Een string is geen formatter.
Als je nou zegt dat elke zelfrespecterende string class een bijpassende formatter class heeft, dan geef ik je helemaal gelijk.
C++, multiple inheritance, etc. Waarom zou een String class geen format method mogen hebben? Het is toch een method die werkt op de data IN de class, hetgeen juist is waar OO voor is bedoeld! Door multiple inheritance kun je je formatter class functionaliteit inbakken in je string class, maar dat hoeft natuurlijk niet. Een string class kan perfect een printf achtige format method hebben, iedere stringclass heeft toch ook een search functie? Of wil je dat ook als 'non-OO' afdoen want het is geen full blown regexp class? :)
De reden hiervoor is dat formatting rekening moet houden met een a priori onbekend aantal UDTs. Kijk maar naar de std:: aanpak. Als je al die formatting data permanent wil meeslepen met elke string, in plaats van alleen voor die strings die je format en alleen gedurende het formatten, dan wordt de overhead van je string class aanmerkelijk groter.
Ja natuurlijk wordt de overhead groter. Je zou de string class die de format methods hebben als een is-a class derivative kunnen zien van de normale stringclass, maar no offence, wat heb je aan een stringclass zonder handige methods op de stringdata IN de class? (Als developer) geen moer, want je kunt dan net zo goed zelf met multibyte arrays gaan lopen rommelen, wat helaas ook veel developers denken te moeten doen.

  • active2
  • Registratie: Juni 2001
  • Laatst online: 17-07 21:56

active2

Google is your friend

Topicstarter
Op vrijdag 26 juli 2002 10:37 schreef Zoijar het volgende:
Algemene oplossing:
code:
1
2
3
4
5
6
7
8
#include &lt;sstream&gt;

template &lt;class T&gt;
std::string toString(const T&amp; i) {
   std::ostringstream sstr;
   sstr &lt;&lt; i;
   return sstr.str();
}
Dit is een hele goeie oplossing maar nu zit ik met het volgende probleem:

strcpy(waarde, toString(100));

Werkt niet.

error:
testje2.cpp: In function `int main(...)':
testje2.cpp:14: cannot convert `basic_string<char,string_char_traits<char>,__default_alloc_template<true,0> >()' from type `basic_string<char,string_char_traits<char>,__default_alloc_template<true,0> >' to type `const char *'

Het heeft wat met die pointers te maken maar ik weet niet hoe ik dit kan oplossen omdat ik nog nooit met die templates gewerkt heb.

[/me] is overigens druk aan het lezen :)

Google, Het mirakel van de 21e eeuw!!!!


Verwijderd

Op vrijdag 26 juli 2002 13:56 schreef Zoijar het volgende:
[..]
Als je String class zelf formatting doet, wordt het heel lastig om (een vorm van) Locales te gebruiken. Het is erg interessant om de C++ stream classes is helemaal door te gaan, en uit te zoeken op welk punt er nou uiteindelijk een character wordt geschreven. Petje af voor degene die dit ontworpen hebben hoor!
Mja, het zal allemaal best knap zijn, maar of het allemaal nodig is in de meeste gevallen betwijfel ik. String processing is HET grote manko van C en C++ achtige talen, bij gebrek aan native stringtypes, waardoor je snel geneigd bent te gaan kijken naar classes die dat dan voor je oplossen. Locales zijn imho juist voor de interpretatie van de multibyte (unicoded) stringdata, dus of je dat soort logica in je stringclass wilt, is natuurlijk vers 2.

Ik zal wel als een domme boer klinken maar ik kan me niet aan de indruk onttrekken dat de functionaliteit zoals die wordt geleverd door bv CString (heb ik het even niet over de interne crappyness van die class ;) ) voor het leeuwendeel van de C++ developers die uberhaupt met strings wordt geconfronteerd meer dan genoeg is, waardoor de developer niet hoeft na te denken of de stringclass iets kan wat hij nodig heeft, dat kan de stringclass. Blijft dus meer tijd over voor de echte logica. De std:: string class heeft ook vrij veel van deze functionaliteit in zich en is dan ook zeer bruikbaar.

Veel mensen neigen ernaar om de meest algemene oplossing als de 'beste' te betitelen, maar algemenisering komt altijd met een prijs, evenals verregaande specialisatie. Als je ziet wat voor gemak een string type in C# oplevert, wil je die functionaliteit gewoon in C++, hoe dat verder geregeld wordt zal de developer worst zijn. Of dat door een serie templates wordt geregeld of door 3 inheritance bomen, is dat nou belangrijk? Het gaat erom dat de developer een stringclass tot zn beschikking heeft die de Basic (pun intended) handelingen op een string uit kan voeren zonder morren. Dat je uiteraard wilt dat unicode support standaard is, is logisch.
Als je alleen ascii wilt kan je gewoon std::basic_ostringstream<char> gebruiken. Anders wchar. (char is per definitie 1 byte, dit hoeven echter geen 8 bits te zijn ;) )
waarom geen basic_string<char> ?
Sinds wanneer is 1 byte geen 8 bits? 1 char is niet altijd 1 byte (per taal verschillend)

Verwijderd

Op vrijdag 26 juli 2002 14:13 schreef active2 het volgende:
Dit is een hele goeie oplossing maar nu zit ik met het volgende probleem:

strcpy(waarde, toString(100));

Werkt niet.

Het heeft wat met die pointers te maken maar ik weet niet hoe ik dit kan oplossen omdat ik nog nooit met die templates gewerkt heb.
De toString() retourneert geen char* maar een std::string. Je zult dus die std::string nog moeten omzetten naar een char*:
code:
1
strcpy(waarde, toString(100).c_str());

Overigens is dit nog steeds riskant programmeren, je werkt nog altijd met char* en moet zelf voldoende ruimte voor je strings alloceren. Als je uitsluitend met std::string werkt heb je die problemen niet, dan gaat alles automatisch goed:
code:
1
string waarde= toString(100);

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Op vrijdag 26 juli 2002 14:20 schreef Otis het volgende:

String processing is HET grote manko van C en C++ achtige talen, bij gebrek aan native stringtypes, waardoor je snel geneigd bent te gaan kijken naar classes die dat dan voor je oplossen.
Dat is het hele concept van OO. Wat is het verschil tussen een native string type en bv. std::string? Ik vind persoonlijk dat C++ perfect met strings omgaat. De standaard IO library is fantastisch.
Locales zijn imho juist voor de interpretatie van de multibyte (unicoded) stringdata, dus of je dat soort logica in je stringclass wilt, is natuurlijk vers 2.
Kan, maar locales zijn er ook voor om bv getallen anders te formatten. Neem USD 10,123,456.78 en INR 1,01,23,456.78 en EUR 10.123.456,78. Als je string class zelf al die varianten moet kunnen parsen wordt het een soort monolith.
ik kan me niet aan de indruk onttrekken dat de functionaliteit zoals die wordt geleverd door bv CString voor het leeuwendeel van de C++ developers die uberhaupt met strings wordt geconfronteerd meer dan genoeg is, waardoor de developer niet hoeft na te denken of de stringclass
CString is idd een microsoft creatie en geen ISO/ANSI. Maar je kan toch heel simpel werken juist met de io lib van C++? Alle details zijn geencapsuleert in classes.
Veel mensen neigen ernaar om de meest algemene oplossing als de 'beste' te betitelen, maar algemenisering komt altijd met een prijs,
De enige prijs in C++ is wat performance. Daarmee heb je wel uit extendable, international, platform onafhankelijke oplossing, die ook nog is heel simpel te gebruiken is. (hoeveel makelijker kan het dan std::cout << i << std::endl; ?)
waarom geen basic_string<char> ?
Sinds wanneer is 1 byte geen 8 bits? 1 char is niet altijd 1 byte (per taal verschillend)
Ik dacht dat we het nu over formatting van unicode hadden, als je alleen een string nodig hebt, ja dan is basic_string<char> natuurlijk ook goed.

In C++ is 1 char per iso standaard gelijk aan 1 byte. Ik dacht dat we het over C++ hadden. In Java is het idd bv 2 bytes. Heb je gelijk in. Dat van die bits was een beetje flauw, je kan in principe een machine maken waar een byte bv 9 bits is, of 32. Een byte is de minimale grootte van een geheugen unit. Maar dat is theoretisch gezwam hehe.

Verwijderd

ik snap nog steeds niet helemaal wat er bedoeld wordt...
Maar kijk hier maar eens naar:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
typedef unsigned long dword;
typedef byte err;

err str_from_dec(char *str, dword dec, dword min_digit)
{
   char digits[11] = &quot;0123456789&quot;;
   dword div, dig, rdig;
  if (!str)
    return 0;
  dig = 0;
  rdig = 0;
  for (div = 1000000000; div; div /= 10, rdig++)
    if ((dec / div != 0) || (dig) || (div &lt;= 1) || (10 - rdig &lt;= min_digit))
    {
    str[dig] = digits[dec / div];
    dec -= (dec / div) * div;
    dig++;
    }
  str[dig] = 0;
  return 1;
}

//------------------------------------------------------------------------------

err str_to_dec(char *str, dword &amp;dec)
{
   dword cur, mul, len;
  if (!str)
    return 0;
  len = str_len(str) - 2;
  if ((len &gt; 9) || (len == -1))
    return 0;
  dec = 0;
  mul = 1;
  for (cur = 0; str[cur]; cur++)
  {
    if ((str[len - cur] &lt; '0') || (str[len - cur] &gt; '9'))
    return 0;
    dec += mul * (str[len - cur] - '0');
    mul *= 10;
  }
  return 1;
}

Volgens mij heb ik deze functies ooit sneller geschreven, dan dat jij er een bestaande methode voor hebt gevonden :+

Verwijderd

Op vrijdag 26 juli 2002 14:40 schreef Zoijar het volgende:
Dat van die bits was een beetje flauw, je kan in principe een machine maken waar een byte bv 9 bits is, of 32. Een byte is de minimale grootte van een geheugen unit. Maar dat is theoretisch gezwam hehe.
In principe? Het is te merken dat jullie van de PC-generatie zijn ;) Vroeger werden er massa's machines geproduceerd met 7, 9, 10, 11 of nog bizardere aantallen bits-per-byte. De PDP-serie was wat dat betreft legendair.

[url="http://pdp10.nocrew.org/docs/instruction-set/Byte.html"]http://pdp10.nocrew.org/docs/instruction-set/Byte.html[/url]
Text strings are typically stored using seven-bit bytes, five per word.
Eeeevil >:)

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Op vrijdag 26 juli 2002 15:07 schreef mietje het volgende:

Eeeevil >:)
Haha, ja behoorlijk :) Wist wel dat het bestond, maar gelukkig nooit mee hoeven werken :)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 26 juli 2002 14:07 schreef Otis het volgende:

[..]

C++, multiple inheritance, etc. Waarom zou een String class geen format method mogen hebben? Het is toch een method die werkt op de data IN de class, hetgeen juist is waar OO voor is bedoeld! Door multiple inheritance kun je je formatter class functionaliteit inbakken in je string class, maar dat hoeft natuurlijk niet. Een string class kan perfect een printf achtige format method hebben, iedere stringclass heeft toch ook een search functie? Of wil je dat ook als 'non-OO' afdoen want het is geen full blown regexp class? :)
Search hoort eigenlijk ook niet in een string, om precies de reden die je aangeeft. Dit kan nog worden getolereerd omdat search niet afhankelijk is van een willekeurig aantal andere types.
Format daarentegen moet alle types formatten
Ja natuurlijk wordt de overhead groter. Je zou de string class die de format methods hebben als een is-a class derivative kunnen zien van de normale stringclass, maar no offence, wat heb je aan een stringclass zonder handige methods op de stringdata IN de class?
Veel - het is bijvoorbeeld een een handig return type voor losse formatters. Andere goede reden: je kunt meer formatters hebben buiten de string class. Zo heeft mijn huidige proggie een class om SMSjes te formatten voordat ik ze naar Ben stuur, en voordat ik ze naar KPN stuur. Dat is dus geen formatter in de SMS class.

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


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 26 juli 2002 14:13 schreef active2 het volgende:

[..]

Dit is een hele goeie oplossing maar nu zit ik met het volgende probleem:

strcpy(waarde, toString(100));

Werkt niet.
std::string waarde;
...
waarde = toString(100);

char* en = werken niet altijd zoals je verwacht. std::string en = doen dat wel.

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

Op vrijdag 26 juli 2002 15:07 schreef mietje het volgende:

[..]

In principe? Het is te merken dat jullie van de PC-generatie zijn ;) Vroeger werden er massa's machines geproduceerd met 7, 9, 10, 11 of nog bizardere aantallen bits-per-byte. De PDP-serie was wat dat betreft legendair.

[url="http://pdp10.nocrew.org/docs/instruction-set/Byte.html"]http://pdp10.nocrew.org/docs/instruction-set/Byte.html[/url]
*sniff* maar ik ben helemaal niet van de patat^H^H^H^H^HPC generatie! *snik*

/me koestert zn toshiba hx-10 memories.

Maar laten we nu maar aannemen dat een byte 8 bits is per definitie, als de basisdefinities van de bouwstenen van de definities bediscussieerd worden, dan is het einde zoek ;)
[Text strings are typically stored using seven-bit bytes, five per word.]
Eeeevil >:)
De reden overigens waarom ASCII 7 bits is ;)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 26 juli 2002 15:00 schreef unteraarsch het volgende:
ik snap nog steeds niet helemaal wat er bedoeld wordt...
Maar kijk hier maar eens naar:
code:
1
2
3
4
5
6
typedef unsigned long dword;
typedef byte err;
...
  for (div = 1000000000; div; div /= 10, rdig++)
...
}

Volgens mij heb ik deze functies ooit sneller geschreven, dan dat jij er een bestaande methode voor hebt gevonden :+
Ja - maar die gevonden functie doet het wel op 64 bits machines. Of 16 bits. En de assembly die pak'em beet MSVC gebruikt is waarschijnlijk sneller. Dus?

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

Op vrijdag 26 juli 2002 15:35 schreef MSalters het volgende:
[..]
Search hoort eigenlijk ook niet in een string, om precies de reden die je aangeeft.
Het opzoeken van een zekere index met als gegeven een substring is wel een van de operaties die je juist wilt zien in een stringclass, immers je kunt anders net zo goed zelf met een forloop een block memory doorfietsen. Jij klinkt alsof je geen methods wilt op de data die encapsulated is in het object. Lijkt me een rare zaak.
Dit kan nog worden getolereerd omdat search niet afhankelijk is van een willekeurig aantal andere types.
Format daarentegen moet alle types formatten
Nee, Format moet de mogelijkheid hebben de gegeven inputobjects om te zetten naar string. Iets dat de objects zelf moeten aangeven, of ze moeten een well known base type hebben.
[..]
Veel - het is bijvoorbeeld een een handig return type voor losse formatters. Andere goede reden: je kunt meer formatters hebben buiten de string class. Zo heeft mijn huidige proggie een class om SMSjes te formatten voordat ik ze naar Ben stuur, en voordat ik ze naar KPN stuur. Dat is dus geen formatter in de SMS class.
Mja, een string zonder methods teruggeven als resultaat van een method is toch een array met words of zie ik dat verkeerd? Begrijp me niet verkeerd: voor veel stringgebruik is een lightweight stringclass te prefereren en niet een kolossale class als bv CString of lookalikes. Derivatives kunnen echter in gevallen wanneer meer functionaliteit vereist is, dat gat opvullen. Ik zie niet in waarom er per se 1 string class moet zijn die nauwelijks methods heeft waar je wat aan hebt, wanneer je hem vergelijkt met een array van words.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

64 bit machine...of 11 bit broodrooster, of zo'n koffie automaat op de gang, of anders wel die ernaast, die snickers enzo uitspuugt voor je zuur verdiende euros...of dollars. Ohja, en ook die schoensmeer machine in dat hotel in thailand die ipv westerse thaise getallen invoert en output ;) Standaard C++ is leuk *D

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 26 juli 2002 14:20 schreef Otis het volgende:

[..]

Mja, het zal allemaal best knap zijn, maar of het allemaal nodig is in de meeste gevallen betwijfel ik. String processing is HET grote manko van C en C++ achtige talen, bij gebrek aan native stringtypes, waardoor je snel geneigd bent te gaan kijken naar classes die dat dan voor je oplossen. Locales zijn imho juist voor de interpretatie van de multibyte (unicoded) stringdata, dus of je dat soort logica in je stringclass wilt, is natuurlijk vers 2.
Locale's zijn idd weer zo'n goede reden waarom je geen formatter in je string class wil.
Overigens is de volgende regel over multibyte/Unicode op een aantal punten fout. Multibyte strings zijn hele andere dingen als Unicode; in het eerste geval is een letter 1 of meer chars (bv Japanse shift-JIS encoding), in het tweede geval is een letter een wchar_t. Locales hebben daar niks mee te maken, die bepalen waar de '.' ( of L'.' :) ) in een float komt
Veel mensen neigen ernaar om de meest algemene oplossing als de 'beste' te betitelen, maar algemenisering komt altijd met een prijs, evenals verregaande specialisatie. Als je ziet wat voor gemak een string type in C# oplevert, wil je die functionaliteit gewoon in C++, hoe dat verder geregeld wordt zal de developer worst zijn. Of dat door een serie templates wordt geregeld of door 3 inheritance bomen, is dat nou belangrijk? Het gaat erom dat de developer een stringclass tot zn beschikking heeft die de Basic (pun intended) handelingen op een string uit kan voeren zonder morren. Dat je uiteraard wilt dat unicode support standaard is, is logisch.
Ik krijg toch een beetje het idee dat je twee dingen vewart, namelijk wat er in een class wordt geleverd, en wat er bij een class wordt geleverd. Het eerste moet je namelijk altijd met die class meeslepen, het tweede alleen als je het nodig hebt. Daarom is het tweede te verkiezen voor alle functionaliteit die beperkt gebruikt wordt.

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


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 26 juli 2002 15:07 schreef mietje het volgende:

[..]

In principe? Het is te merken dat jullie van de PC-generatie zijn ;) Vroeger werden er massa's machines geproduceerd met 7, 9, 10, 11 of nog bizardere aantallen bits-per-byte. De PDP-serie was wat dat betreft legendair.
En tegenwoordig zijn er GSMs met 32 bits per char. Kortom, blijf een beetje bij de tijd :)

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


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 26 juli 2002 15:43 schreef Otis het volgende:
Het opzoeken van een zekere index met als gegeven een substring is wel een van de operaties die je juist wilt zien in een stringclass, immers je kunt anders net zo goed zelf met een forloop een block memory doorfietsen. Jij klinkt alsof je geen methods wilt op de data die encapsulated is in het object. Lijkt me een rare zaak.
[...]
Mja, een string zonder methods teruggeven als resultaat van een method is toch een array met words of zie ik dat verkeerd? Begrijp me niet verkeerd: voor veel stringgebruik is een lightweight stringclass te prefereren en niet een kolossale class als bv CString of lookalikes.
Nee; een array met words heeft geen memory management - en dat is IMO het cruciale verschil.
Derivatives kunnen echter in gevallen wanneer meer functionaliteit vereist is, dat gat opvullen. Ik zie niet in waarom er per se 1 string class moet zijn die nauwelijks methods heeft waar je wat aan hebt, wanneer je hem vergelijkt met een array van words.
Praktisch gezien is noch std::string noch CString een bruikbare base class. Geen van beide heeft een virtual dtor, omdat die de class significant langzamer zou maken (en in het geval van CString zelfs de normale functionaliteit onmogelijk maken). Waarom je de methods zou willen toevoegen aan een derived class als je ze ook aan een onafhankelijk formatter object kunt toevoegen is me ook niet duidelijk. Een formatter en een string hebben geen IS-A relatie.

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

Op vrijdag 26 juli 2002 15:53 schreef MSalters het volgende:
[..]
Locale's zijn idd weer zo'n goede reden waarom je geen formatter in je string class wil.
Locales zijn bij een zeker abstractieniveau nuttig, maar niet op _ELK_ abstractieniveau. Goed voorbeeld hiervan is bv de stringformatters in VBScript vs de stringformatters in C#. Dit houdt in dat je OF kiest voor een formatter die een uniforme formatdefinitiestring eet en op basis van locales de formatting doet (bv VBScript/VB6 format functies doen dat), je kunt ook kiezen voor een formatstring waar de expliciete formatteringsdefinitie in opgeslagen is, en het is aan de developer welke aangevoerd wordt. (maw: je formatter is wars van locale-related formatting issues). De een zit op een ander abstractieniveau dan de ander.
Overigens is de volgende regel over multibyte/Unicode op een aantal punten fout. Multibyte strings zijn hele andere dingen als Unicode; in het eerste geval is een letter 1 of meer chars (bv Japanse shift-JIS encoding), in het tweede geval is een letter een wchar_t.
Multibyte vs Unicode is my bad idd, ik haalde MBCS en Unicode door elkaar, dat had niet gemoeten.
[..]
Ik krijg toch een beetje het idee dat je twee dingen vewart, namelijk wat er in een class wordt geleverd, en wat er bij een class wordt geleverd. Het eerste moet je namelijk altijd met die class meeslepen, het tweede alleen als je het nodig hebt. Daarom is het tweede te verkiezen voor alle functionaliteit die beperkt gebruikt wordt.
Mja, ik zie dit toch echt anders. OO is data-oriented, en IMHO is het t.a.t. te verkiezen op data-type X werkende functionaliteit te plaatsen in classes van data-type X of daaraan gerelateerde classes. Men praat dan wel vrolijk over universele libraries van methods, maar in feite is dat procedural denken, en niet data-oriented denken. Als je top-down over een string gaat redeneren, dan kun je in principe een core string definieren met puur memmanagenent en basic functies, en daar meerdere typen van deriven met ieders hun specialisme.

Je kunt _OOK_ kiezen voor alleen de core string class en een serie static methods die allerlei dingen doen met een string object of meerdere string objects. IMHO echter is dit meer C-style denken dan puur OO, dataoriented. C heeft geen generics, had C die wel gehad, dan hadden we over een core class gepraat, string, en verder louter C-style code.

  • Ghost(NL)
  • Registratie: December 2000
  • Niet online
Op vrijdag 26 juli 2002 10:21 schreef MSalters het volgende:

[..]

De _ aan het begin is een redelijke hint dat het een MS-only extensie is. snprintf() in C, of std::ostringstream in C++ zijn de standaard methoden, boost::lexical_cast<std::string> werkt ook

En verder wil je in C++ std::string gebruiken ipv char*
Om ff terug te komen op dit, 5 sec. zoeken op mijn rh machientje leerde mij dat onder linux je de functie strtol hebt met bijna dezelfde parameters

zie hier:

long int strtol(const char *nptr, char **endptr, int base);

maw. microsoft en die nog niet eens maar ik geloof borland hebben het wat logischer gemaakt en van de combi atoi - strtol de combi atoi - itoa gemaakt en het _ duidt naar mijn weten niet op zozeer op een microsoft implementatie maar meer op een "legacy" functie.

i5-12600K PRIME Z690M-PLUS D4 64GB 980 Pro M.2 1TB  MBA M1 13" 8GB 256GB (Late '20)


Verwijderd

Op vrijdag 26 juli 2002 16:04 schreef MSalters het volgende:
Fout, ik wil geen methods die net zo goed free functions kunnen zijn. std::search op string iterators kan precies net zo efficient zijn als een search method. Alleen die functies waarbij geheugenallocaties relevant zijn zouden dus methods moeten zijn; die allocatie strategie is nl. het enige wat een string class private moet houden.
'free functions' ? Je bedoelt static methods die algemene zaken behartigen? Waarom zou je die verkiezen boven de data-oriented aanpak, die de basis vormt voor OO? Verder zie ik de theoretische basis niet voor het NIET plaatsen van zekere bewerkingsmethods op de stringclass, temeer omdat dit semantisch zeer juist zou zijn, immers, de data zit IN de class en de methods die werken OP die data zitten OOK in die class. Jij wilt ze daar niet omdat dat performance/memory kost. IMHO _nooit_ een reden voor het kiezen van wat 'juist' is, alleen in die situatie waar wat 'juist' is er niet toe doet maar performance/memory management telt (bv in de embedded wereld).

Jouw redenatie volgend, zouden ALLE classes alleen maar met memory management moeten worden uitgerust en verder alle logica in static methods moeten worden geplaatst. Leg me aub dan eens uit waarom dat dan WEL puur OO is en de methods plaatsen IN de class (of in gespecialiseerde derivatives) niet.
[..]
Praktisch gezien is noch std::string noch CString een bruikbare base class. Geen van beide heeft een virtual dtor, omdat die de class significant langzamer zou maken (en in het geval van CString zelfs de normale functionaliteit onmogelijk maken). Waarom je de methods zou willen toevoegen aan een derived class als je ze ook aan een onafhankelijk formatter object kunt toevoegen is me ook niet duidelijk. Een formatter en een string hebben geen IS-A relatie.
Ik zei ook niet dat CString moest dienen als base class, CString is een zeer uitgebreide class en zou eerder als voorbeeld voor een specialistische derivative gelden. Waarom methods niet toevoegen aan een class en wel aan een onafhankelijke formatter? Nou omdat Object Oriented development zich richt op de data, de relaties tussen de data en de functionaliteit OP die data, niet op libraries van static functies die werken op louter baseclasses, en waarbij inheritance niet wordt gebruikt om de functionalteit die werkt op een zekere data uit te breiden maar de functionaliteit in het algemeen uit te breiden, zonder dat deze is gerelateerd aan data (dus is gesitueerd in een class).

Maar dit glijdt af naar een 'wat is OO' discussie en dat is een dead-beat-horse. :)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 26 juli 2002 16:40 schreef ghostrdr01 het volgende:

[..]

Om ff terug te komen op dit, 5 sec. zoeken op mijn rh machientje leerde mij dat onder linux je de functie strtol hebt met bijna dezelfde parameters

zie hier:
long int strtol(const char *nptr, char **endptr, int base);
Ascii TO Int
STRint TO Long

Niet echt een heel verschil he?

atoi is gewoon makkelijker (in C) omdat je weet dat er sizeof(int) bytes uitkomen, van itoa weet je dat niet a priori.

C++ers gebruiken gewoon boost::lexical_cast van en naar std::string, dat is pas symmetrisch

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

In C++ is het idd vaak beter gewoon de std functies te kiezen ipv de oude CRT functies. De std is wel vrij ontoegankelijk voor novice C++-ers, maar het schijnt beter te worden na een tijdje ;)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 21-08 17:14
Op vrijdag 26 juli 2002 16:42 schreef Otis het volgende:
'free functions' ? Je bedoelt static methods die algemene zaken behartigen? Waarom zou je die verkiezen boven de data-oriented aanpak, die de basis vormt voor OO?
Nee, ik bedoel free functions buiten de class, die NIET met de class internals rotzooien. Als je een bug in een class wil lokaliseren, waardoor private members veranderen, hoef je alleen members te doorzoeken. Hoe minder members hoe beter. Static members hebben access privileges op private members/methods. Free functions die dezelfde functionalieit bieden zijn daarom te verkiezen (zie ook Scott Meyers)
Verder zie ik de theoretische basis niet voor het NIET plaatsen van zekere bewerkingsmethods op de stringclass, temeer omdat dit semantisch zeer juist zou zijn, immers, de data zit IN de class en de methods die werken OP die data zitten OOK in die class. Jij wilt ze daar niet omdat dat performance/memory kost. IMHO _nooit_ een reden voor het kiezen van wat 'juist' is, alleen in die situatie waar wat 'juist' is er niet toe doet maar performance/memory management telt (bv in de embedded wereld).
Laat ik even aannemen dat je bedoelde "zelden een doorslaggevende reden".
Mijn primaire reden is dat de complexiteit van software vereenvoudigd wordt als er meer onafhankelijke entiteiten met beperkte interfaces zijn. Een free function is op die manier simpeler omdat deze alleen bij de publieke data interface kan.
Jouw redenatie volgend, zouden ALLE classes alleen maar met memory management moeten worden uitgerust en verder alle logica in static methods moeten worden geplaatst.
Nee, alleen classes die memory management uitvoeren horen zich te beperken tot memory management. String is zo'n class die memory management doet voor chars.
Leg me aub dan eens uit waarom dat dan WEL puur OO is en de methods plaatsen IN de class (of in gespecialiseerde derivatives) niet.
Als ik een C programma neem, en ik plaats alle functies daarvan in een class (als [static] methods) is dat dan OO?

Nee, natuurlijk niet. OO heeft niets te maken met de plaatsing van dit soort functies. OO gaat veel meer over het bewaken van invarianten, zoals "de string class weet op elk moment hoeveel chars er gemanaged worden" en "de string class kan op elk moment alle chars dealloceren".
Waarom methods niet toevoegen aan een class en wel aan een onafhankelijke formatter? Nou omdat Object Oriented development zich richt op de data, de relaties tussen de data en de functionaliteit OP die data, niet op libraries van static functies die werken op louter baseclasses, en waarbij inheritance niet wordt gebruikt om de functionalteit die werkt op een zekere data uit te breiden maar de functionaliteit in het algemeen uit te breiden, zonder dat deze is gerelateerd aan data (dus is gesitueerd in een class).
Precies! Je slaat hiet de spijker op z'n kop. Een formatteer actie legt de relatie tussen
1) een aantal input objecten
2) een format specificatie
3) het eindresultaat ( een string ).

Deze functie toewijzen aan 3 is wel bijzonder vreemd. Als het al ergens bijhoort is het wel bij 2. En je ziet dus dat nieuwere C++ voorstellen voor formatters eruitzien als
code:
1
2
3
4
format pair(&quot;(%2 %1)&quot;);

std::string output_num = pair(3,4);
std::string output_text = pair(&quot;A&quot;,&quot;B&quot;);

Hierin is pair een formatter object, met als formatting functie operator(). De output is dus de strings "(4 3)" en "(B A)".

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


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Het is een bekend feit dat veel C++ers te vaak en te veel inheritance gebruiken, en dan ook vaak nog naar de verkeerde kant.

Als voorbeeld met die string, je gaat dus niet een basis string class maken, en daar nieuwe classes van afleiden die specifieke formatting doen (stel even dat je de formatting in de string class zou plaatsen). Je krijgt dan een soort explosie van string classes, en onderlinge dependencies.

Het is veel beter om dan enkele kleine classes te schrijven, ofwel policies, en je string af te leiden van de policy classes die je nodig hebt via multiple inheritance. Je reduceert je afhankelijkheden dan.

Als je nog verder gaat, zou het ideaal zijn als je dit soort dingen compleet buiten de string class kan halen. Het begrip van encapsulatie/data hiding gaat niet alleen op voor de eindgebruiker, maar ook tussen classes. Zo min mogelijk code moet toegang hebben tot private members.

In de standaard library zie je al deze concepten heel duidelijk naar voren komen. Misschien is dit boek een aanrader, als je het C++ IO model eenmaal echt door hebt, zie je in hoe mooi het in elkaar zit.

"Standard C++ IOStreams and Locales: Advanced Programmer's Guide and Reference" by Angelika Langer, Klaus Kreft

Verwijderd

Op vrijdag 26 juli 2002 17:55 schreef Zoijar het volgende:
Het is een bekend feit dat veel C++ers te vaak en te veel inheritance gebruiken, en dan ook vaak nog naar de verkeerde kant.
Dat komt door de taaltechnische voordelen die C++ en ook sommige andere talen bieden die wel met de OO-gerelateerde methodieken te maken hebben maar niet met OO-denken. Ach, op zich is het niet zo'n probleem, vind ik.
Als voorbeeld met die string, je gaat dus niet een basis string class maken, en daar nieuwe classes van afleiden die specifieke formatting doen (stel even dat je de formatting in de string class zou plaatsen). Je krijgt dan een soort explosie van string classes, en onderlinge dependencies.
Erm, wat is nou de preciese reden waarom niet? Want als we puur naar de algemene OO methodiek kijken wanneer je normaliter een class subclasset, is het wel degelijk semantisch correct om te veronderstellen dat je op basis van een karige base-class dmv generics bijvoorbeeld, gespecialiseerde subclasses maakt. Ik zie niet in waarom een string daar dan niet aan zou moeten voldoen. IEDERE specialisatie van een class levert wellicht meerdere subclasses op en indien je middels generics deze classes implementeert, krijg je een wellicht grote hoeveelheid verschillende. Dat is inherent aan baseclass-subclass.
Het is veel beter om dan enkele kleine classes te schrijven, ofwel policies, en je string af te leiden van de policy classes die je nodig hebt via multiple inheritance. Je reduceert je afhankelijkheden dan.
Multiple inheritance vergroot toch juist afhankelijkheden, of zie ik het verkeerd? :) Multiple inheritance kan een oplossing zijn voor grote inheritance trees. Via generics kun je ook ver komen IMHO.

Wat mijn punt is, is dat er een uitzonderingspositie schijnt te moeten worden gemaakt voor de 'formatting' method bij een 'string' class. Dit lijkt me echter onzin, daar bv het resultaat van de formatting method de inhoud van het stringobject bepaalt, en dus wel degelijk net als een assignment operator thuis hoort in de stringclass (of een concatoperator die de right operand plakt achter de huidige toestand van de stringclass). Waarom zou dan de formatting method niet thuis horen in de string class? Omdat er dan vele stringclasses komen? Mja, maar daar is toch 'generics' voor uitgevonden?
Als je nog verder gaat, zou het ideaal zijn als je dit soort dingen compleet buiten de string class kan halen. Het begrip van encapsulatie/data hiding gaat niet alleen op voor de eindgebruiker, maar ook tussen classes. Zo min mogelijk code moet toegang hebben tot private members.
Een format method doet toch net als een assignment operator iets met de classcontents? ALs je de format BUITEN de stringclass haalt, is dat dus een method die dus niet alleen strings op hoeft te leveren maar ook een ander type. In _DIE_ algemeenheid, ja, dan is dat logisch, echter levert je formattingclass alleen strings op, waarom zit die functionaliteit niet in de stringclass zelf (of een derived versie)? Immers hij is onlosmakelijk verbonden met de stringclass en werkt op de inhoud van de stringclass. Hoe kun je een method A (formatting) dan wel buiten de stringclass halen en een method B (assignment) niet, terwijl beide de contents van de class bepalen. Een formatting is toch niets anders dan een speciale assignment.
In de standaard library zie je al deze concepten heel duidelijk naar voren komen. Misschien is dit boek een aanrader, als je het C++ IO model eenmaal echt door hebt, zie je in hoe mooi het in elkaar zit.
"Standard C++ IOStreams and Locales: Advanced Programmer's Guide and Reference" by Angelika Langer, Klaus Kreft
Ik zou liever zien dat C++ meer typen en statements kreeg die de std overbodig maken. De std is een knap staaltje werk, maar als je kijkt naar bv het gemak van java en C# en je vergelijkt dat met C++, dan zou je soms willen dat dat gemak (tezamen met het gemak van C++ ;) ) gebundeld werd.

Ik denk dat we van mening verschillen omtrent wat je in een class bundelt en waarom. Het is niet 'goed vs fout', maar meer verschillende visies op dit thema. Immers, je kunt er idd voor pleiten een serie algemene classes te definieren die bulkwerk uit handen nemen, en omdat je die met generics opzet zijn ze overal inzetbaar en ontlast je de doorgaans veelgebruikte andere classes die daardoor lichter worden. Anderen, waaronder yours truely :P, vinden dit toch meer een uitholling van het pure OO / dataoriented denken. C'est la vie. :)

Verwijderd

Op vrijdag 26 juli 2002 17:23 schreef MSalters het volgende:
[..]
Nee, ik bedoel free functions buiten de class, die NIET met de class internals rotzooien. Als je een bug in een class wil lokaliseren, waardoor private members veranderen, hoef je alleen members te doorzoeken. Hoe minder members hoe beter. Static members hebben access privileges op private members/methods. Free functions die dezelfde functionalieit bieden zijn daarom te verkiezen (zie ook Scott Meyers)
Ja ok, maar die functies zitten ergens in, ik neem aan static. Dat bedoelde ik. Niet static in bv de stringclass :)
[..]
Laat ik even aannemen dat je bedoelde "zelden een doorslaggevende reden". Mijn primaire reden is dat de complexiteit van software vereenvoudigd wordt als er meer onafhankelijke entiteiten met beperkte interfaces zijn. Een free function is op die manier simpeler omdat deze alleen bij de publieke data interface kan.
Mij hoor je ook niet zeggen dat procedureel denken foutief is oid :) Ik vind alleen dat wanneer je data-oriented bezig bent, en functionaliteit implementeert die werkt op die data, je die functionaliteit bij die data moet implementeren. Ik vind dat een logische en daardoor heldere manier van werken, immers de functionaliteit die werkt op de data van type 'string' is gedefinieerd bij dat type of baseclasses en nergens anders, niet in een of andere library of andere class.

Het is denk ik wat je prefereert. Ik kom uit de C wereld en ken de ellende van functies die wel ergens bijhoorden maar je kon dat behalve middels modules niet echt kenbaar maken.
[..]
Nee, alleen classes die memory management uitvoeren horen zich te beperken tot memory management. String is zo'n class die memory management doet voor chars.
Agreed, maar ik wil ook graag een simpele class die dat doet wat die string class doet van jou PLUS basic stringhandling zoals concatenation, simpele formatting, splitting enz., je weet wel, die dingen die bij string-intensieve code een slok op een borrel schelen :) Waarom zou je daarvoor dan niet een serie specialised classes maken, zodat wanneer je die extra functionaliteit niet nodig hebt, je de baseclass neemt, en wanneer je het wel nodig hebt een gespecialiseerde class. Ik zie het probleem niet echt hoor. (zie ook onder)
[..]
Als ik een C programma neem, en ik plaats alle functies daarvan in een class (als [static] methods) is dat dan OO?
Nee, natuurlijk niet. OO heeft niets te maken met de plaatsing van dit soort functies. OO gaat veel meer over het bewaken van invarianten, zoals "de string class weet op elk moment hoeveel chars er gemanaged worden" en "de string class kan op elk moment alle chars dealloceren".
mja, zoalsik zei: 'wat is OO' ligt op de loer, dus daar ga ik niet in mee :), wat het probleem is is dat er verschillende visies zijn op het fenomeen 'OO' met alle fijne spraakverwarringen en discussies van dien. :) We zitten duidelijk niet in hetzelfde groepje, wat ook zoiets betekent als dat we het hierover echt niet eens gaan worden :)
[..]
Precies! Je slaat hiet de spijker op z'n kop. Een formatteer actie legt de relatie tussen
1) een aantal input objecten
2) een format specificatie
3) het eindresultaat ( een string ).
Deze functie toewijzen aan 3 is wel bijzonder vreemd. Als het al ergens bijhoort is het wel bij 2.
NEE! :)
De formatter is niet een functie zoals printf dat is! Dan had je gelijk. De formatter is een speciale assigment functie. '=' doet geen formatting en maakt de right operand als inhoud van het string object, 'Format()' doet eerst een formatting van de parameters en maakt het resultaat de inhoud van het string object.

Zie je het als algemene gehaktmolenfunctie, dus duw er iets in en er komt een string uit, wat je er mee doet moet je zelf weten, ja, dan is het plaatsen bij de string bediscussieerbaar. Zie je het als een internal assignment functie, zoals het ook in bv CString is geimplementeerd, dan is dit heel wat anders en een pure method op de interne class' data, zoals dat bij OO gebruikelijk is.

Verwijderd

Op vrijdag 26 juli 2002 18:18 schreef Otis het volgende:
Ik zou liever zien dat C++ meer typen en statements kreeg die de std overbodig maken. De std is een knap staaltje werk, maar als je kijkt naar bv het gemak van java en C# en je vergelijkt dat met C++, dan zou je soms willen dat dat gemak (tezamen met het gemak van C++ ;) ) gebundeld werd.
Het voordeel van een library-georienteerde taal tov. een keyword-georienteerde taal is dat de (basis)taal daardoor veel breder inzetbaar wordt. C++ probeert de gebruikersvriendelijkheid van een keyword-georienteerde taal te benaderen door de mogelijkheid keywords (operatoren) te overloaden.

Het invoeren van string als een atomair type (ik neem aan dat je dat bedoelt) in een taal vind ik een draak, want een string is geen atomair type maar een geordende verzameling karakter-atomairen.

Onder de streep is het enige verschil dat een applicatieprogrammeur opmerkt tussen een keyword-aanpak en een overloading plus library-aanpak, het feit dat hij headers moet includen en de bewuste libraries mee moet linken.
Ik denk dat we van mening verschillen omtrent wat je in een class bundelt en waarom. Het is niet 'goed vs fout', maar meer verschillende visies op dit thema. Immers, je kunt er idd voor pleiten een serie algemene classes te definieren die bulkwerk uit handen nemen, en omdat je die met generics opzet zijn ze overal inzetbaar en ontlast je de doorgaans veelgebruikte andere classes die daardoor lichter worden. Anderen, waaronder yours truely :P, vinden dit toch meer een uitholling van het pure OO / dataoriented denken. C'est la vie. :)
Ook OOP is een kwestie van afwegen hoe ver je je software "doordesigned", maw. hoe ver dat je je probleem abstraheert. Zo kun je er om verschillende redenen voor pleiten bepaalde zware actor-methods op een object verder te abstraheren tot zelfstandige actor-objects, zoals MSalters dat doet. Dat is geheel in de geest van OOD.

Verwijderd

Op vrijdag 26 juli 2002 18:43 schreef mietje het volgende:
[..]
Het voordeel van een library-georienteerde taal tov. een keyword-georienteerde taal is dat de (basis)taal daardoor veel breder inzetbaar wordt. C++ probeert de gebruikersvriendelijkheid van een keyword-georienteerde taal te benaderen door de mogelijkheid keywords (operatoren) te overloaden.
Op zich is hier wel veel voor te zeggen, ik vind C++ er alleen niet vriendelijker op worden als je kijkt wat je moet kennen van de std wil je er effectief gebruik van maken. Je zit dan met 2 gedeelten die je moet leren: EN C++ EN de std.
Het invoeren van string als een atomair type (ik neem aan dat je dat bedoelt) in een taal vind ik een draak, want een string is geen atomair type maar een geordende verzameling karakter-atomairen.
Mja, een float is in theorie ook een type bestaand uit een aantal onderdelen. Dezelfde discussie woedde een week geleden in de C# newsgroep omtrent de struct als valuetype, of dat nu wel of niet een goed ding was. Ik vind van wel, een Complex number type kun je dan toch atomair behandelen alsof het een valuetype is. Met strings is het imho net zo, immers, je behandelt ze altijd als valuetypes. (In .NET cheaten ze hoor, ze doen onder water gewoon new System.String(value)) Dat men sinds mensenheugenis strings ziet als arrays van chars of soortgelijke elements, is IMHO een leftover van het fenomeen dat de talen van weleer geen ingebakken stringtype hadden. Echter voor de developer maakt het toch niet uit HOE de compiler en de RTL er mee omgaan, het gaat om het feit dat mensen op een abstract niveau met strings kunnen omgaan zonder de overhead die er anders altijd mee gemoeid is.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Op vrijdag 26 juli 2002 20:29 schreef Otis het volgende:

Ik vind van wel, een Complex number type kun je dan toch atomair behandelen alsof het een valuetype is. Met strings is het imho net zo, immers, je behandelt ze altijd als valuetypes. (In .NET cheaten ze hoor, ze doen onder water gewoon new System.String(value)) Dat men sinds mensenheugenis strings ziet als arrays van chars of soortgelijke elements, is IMHO een leftover van het fenomeen dat de talen van weleer geen ingebakken stringtype hadden. Echter voor de developer maakt het toch niet uit HOE de compiler en de RTL er mee omgaan, het gaat om het feit dat mensen op een abstract niveau met strings kunnen omgaan zonder de overhead die er anders altijd mee gemoeid is.
Wat is voor de gebruiker het verschil tussen, zeg een class Complex, en een build-in type Complex? Je kan in C++ perfect een class maken die zich volledig gedraagt als value type. C++ heeft het zeg maar allemaal, je kan zelf nieuwe types toevoegen. Ik zie een string niet als array van characters hoor als ik dat niet wil. Het is gewoon een std::string en daar kan je dingen mee doen, zoals die string bv naar output sturen. En ik reken met quaternions alsof het floats zijn zeg maar. Ik zie niet in waarom je steeds met dit verschil aan komt, wat het voordeel (nadeel!) is van build-in types.

Verwijderd

Op vrijdag 26 juli 2002 20:29 schreef Otis het volgende:
Op zich is hier wel veel voor te zeggen, ik vind C++ er alleen niet vriendelijker op worden als je kijkt wat je moet kennen van de std wil je er effectief gebruik van maken. Je zit dan met 2 gedeelten die je moet leren: EN C++ EN de std.
Agreed (hoewel ik de STL eigenlijk als een integraal onderdeel van C++ beschouw). Op zich zit de STL erg logisch in elkaar, meestal is het overschakelen op generic programming in het algemeen het struikelblok, dat is conceptueel toch iets moeilijker dan OO. De std::string is echter niet lastiger te hanteren dan bv. een Pascal String.
Met strings is het imho net zo, immers, je behandelt ze altijd als valuetypes.
Echter voor de developer maakt het toch niet uit HOE de compiler en de RTL er mee omgaan, het gaat om het feit dat mensen op een abstract niveau met strings kunnen omgaan zonder de overhead die er anders altijd mee gemoeid is.
Mja, ik doelde het meer op het conceptuele verschil. Hoewel een float intern uit mantissa en exponent bestaat, zal een applicatieprogrammeur die onderdelen nooit individueel benaderen willen. Bij een string kun je er donder op zeggen dat er vroeger of later een applicatieprogammeur is die toegang nodig heeft tot de individuele karakters van die string. En zoals gezegd, de overhead blijft veelal beperkt tot "#include <string>".

(2x "conceptueel" en 1x "integraal" in een post gebruikt, ik ontkom blijkbaar ook niet aan taal-hypes :+)

Verwijderd

Op vrijdag 26 juli 2002 20:59 schreef Zoijar het volgende:
[..]
Wat is voor de gebruiker het verschil tussen, zeg een class Complex, en een build-in type Complex?
Het passen van een instance aan een functie is verschillend. Value types zijn altijd by value, classes impliceren objects en die zijn altijd by reference.
Je kan in C++ perfect een class maken die zich volledig gedraagt als value type. C++ heeft het zeg maar allemaal, je kan zelf nieuwe types toevoegen.
Een class is een object en bij mijn weten heb je dan altijd een pointer naar een vtable en geen value type die in het stackframe is gealloceerd. Hierdoor krijg je wel degelijk verschillend gedrag bij het heen en weer gooien van instances tussen functies.
Ik zie een string niet als array van characters hoor als ik dat niet wil. Het is gewoon een std::string en daar kan je dingen mee doen, zoals die string bv naar output sturen. En ik reken met quaternions alsof het floats zijn zeg maar. Ik zie niet in waarom je steeds met dit verschil aan komt, wat het voordeel (nadeel!) is van build-in types.
het voordeel van build-in types is dat iedereen die de taal kent, de types ook kent. Iemand die niet de stijle leercurve van de std door wil maar bv middels OWL of MFC of weet ik wat voor lib met C++ bezig is, begrijpt je niet als jij iets uit de std aanvoert, terwijl jij dat beschouwt als onderdeel van C++. Met build-in types heb je dat dus niet. C++ heeft gaten in de functionaliteit op het gebied van buildin types, hoe die intern ook worden opgelost. De std vangt die allemaal op, maar zoals gezegd, zonder std is het nog steeds goed mogelijk C++ te programmeren (hell, veel win32 developers die programmeren in C++ gebruiken MFC's classes (v6 of hoger) en atl. Je krijgt dan tweedeling in de gebruikers van 1 taal, terwijl beide groepen dezelfde functionaliteit nastreven. (Los van het feit of valuetypes van structs handig zijn of niet ;) )

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Op vrijdag 26 juli 2002 21:57 schreef Otis het volgende:

Het passen van een instance aan een functie is verschillend. Value types zijn altijd by value, classes impliceren objects en die zijn altijd by reference.
void foo(int& i) {} // value type by reference
void bar(Complex c) {} // object by value

:?
Een class is een object en bij mijn weten heb je dan altijd een pointer naar een vtable en geen value type die in het stackframe is gealloceerd. Hierdoor krijg je wel degelijk verschillend gedrag bij het heen en weer gooien van instances tussen functies.
De standaard zegt niets over vtables, dus kan je er in principe geen uitspraken over doen. (maar iha als er niets virtueel is optimized je compiler het eruit)
Overigens zegt de standaard ook niets over de (byte) grootte van build in types, muv char.
Als je dus volledig via de standaard werkt, zie je ook op het stackframe geen verschil. Een array van complex ziet er hetzelfde uit als een array van int. Misschien niet in je geheugen, maar dat mag je toch niet rechtsreeks aanspreken want dan ben je al niet portable bezig.
het voordeel van build-in types is dat iedereen die de taal kent, de types ook kent.
Iedereen behoort ook de standaard library te kennen, net als je in andere talen de build-in types moet kennen. Dat mensen bv mfc en atl en win32 en std mixen heb je gelijk in, en dat is ook slecht. De leer curve is misschien hoog ja, maar niemand heeft gezegd dat C++ een makkelijke taal is.

Verwijderd

Op vrijdag 26 juli 2002 22:15 schreef Zoijar het volgende:
[..]
void foo(int& i) {} // value type by reference
void bar(Complex c) {} // object by value
:?
Ik drukte me wat te algemeen uit, in C++ heb je memberwise copies die als 'by value' dienen, klopt. En ja valuetypes passen by reference ken ik, ik bedoelde meer: value types declareer je op de stack, reference types definieer je op de heap. Objects zijn normaliter reference types en definieer je dus niet op de stack maar op de heap. Dit deel van de discussie ging over het nut van value types. so there.
[..]
Iedereen behoort ook de standaard library te kennen, net als je in andere talen de build-in types moet kennen.
Huh? waar staat dat geschreven? Lekkere taal, naast de taal, en de api die je gebruikt voor platformaccess heb je ook nog te maken met een 3e tak van sport, de std, die moet je ook kennen, volgens de purist :) Die vlieger gaat niet op.
Dat mensen bv mfc en atl en win32 en std mixen heb je gelijk in, en dat is ook slecht.
Slecht, volgens wie? Een programmeertaal en libraries gebruik je om een zeker doel te bereiken, niet voor de kicks.
De leer curve is misschien hoog ja, maar niemand heeft gezegd dat C++ een makkelijke taal is.
Dat was ook niet het punt.

Verwijderd

Op vrijdag 26 juli 2002 23:54 schreef Otis het volgende:
Objects zijn normaliter reference types en definieer je dus niet op de stack maar op de heap.
Waar heb je dit vandaan :?

Voor zover ik weet is er helemaal niks mis met het gebruiken van de stack voor non-built-in's.

Verwijderd

Op zaterdag 27 juli 2002 00:24 schreef Sneechy het volgende:
[..]
Waar heb je dit vandaan :?
Voor zover ik weet is er helemaal niks mis met het gebruiken van de stack voor non-built-in's.
Voor piepkleine struct/classes zou dat ook niet zo onlogisch zijn, echter waarom zou MS speciaal voor de managed C++ extensions '__value' hebben geintroduceerd om value typed classes te kunnen maken die je naast de runtime heap ook op de stack kunt plaatsen en zo ervoor te zorgen dat de GC niet deze, kleine, classes op hoeft te ruimen? Als je sowieso classes al op de stack kon plaatsen, waarom zou dan dit keyword nodig zijn?

Het is ook niet zo onlogisch hoor, om objectinstances niet op de stack te alloceren maar op de runtime heap. Voor de developer maakt dat niet zoveel uit natuurlijk.

edit:

Hmmm, bij nader inzien flikkert de VC++ compiler wel degelijk grote objects op de stack ipv alleen de vtable + membertable. Odd.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Op zaterdag 27 juli 2002 11:30 schreef Otis het volgende:

die je naast de runtime heap ook op de stack kunt plaatsen en zo ervoor te zorgen dat de GC niet deze, kleine, classes op hoeft te ruimen? Als je sowieso classes al op de stack kon plaatsen, waarom zou dan dit keyword nodig zijn?
Stack en heap allocatie kan je helemaal zelf bepalen, je hebt zelfs nog placement-new in C++, waarmee er alleen heap geheugen wordt gealloceerd en je zelf je object erin kan plaatsen.
Je kan een int op de heap zetten, en ook een CVeryBigClass op de stack. Vaak zet je een object op de heap, en een auto pointer ernaar op de stack.
En verder heeft C++ geen GC :P Ik denk dat die MS extensie een hint naar de compiler is om geen vtable aan te maken, maar de class te behandelen als POD type iets wat een slimme optimizing compiler uit zichzelf al zou kunnen zien.
Het is ook niet zo onlogisch hoor, om objectinstances niet op de stack te alloceren maar op de runtime heap. Voor de developer maakt dat niet zoveel uit natuurlijk.

edit:

Hmmm, bij nader inzien flikkert de VC++ compiler wel degelijk grote objects op de stack ipv alleen de vtable + membertable. Odd.
Het maakt wel degelijk uit aangezien er geen GC is. Stack wordt netjes opgeruimd, heap niet. De normale gang van zaken is om een smart pointer (std::auto_ptr) naar een heap gealloceerd object op de stack te zetten.
Pagina: 1