size_t nach char* (string) Konverter

15/03/2010 - 14:50 von Robert Hartmann | Report spam
Hallo zusammen,

Ich habe mich an einem size_t nach string Konverter
versucht, also einem Konverter der zu einem size_t
die passende Null-terminierte Zeichenkette als char*
zurückliefert.

Ganz glücklich bin ich damit noch nicht,
denn durch die Zeile in test() markiert mit /* ********** */
entsteht eine dynamische Speicherbelegung,
die man nicht mehr frei geben kann, oder?


Kann man es noch irgendwie geschickter machen?

Besten Gruß,
Robert



#include<stddef.h>
#include<assert.h>
#include<stdio.h>

size_t zaehleStellen(size_t zahl, size_t basis) {

assert((basis <6)&&(basis>=1));

if (basis == 1)
return zahl == 0 ? 1 : zahl;

if (zahl == 0)
return 1;

size_t count = 0;
for (size_t i = 1; i <= zahl; i *= basis) {
count++;
}
return count;
}


char * size_t2string(size_t zahl, size_t basis) {

assert((basis <6)&&(basis>=1));

size_t stringStellen = zaehleStellen(zahl, basis) + 1;
char * ret = NULL;
ret = (char*) malloc(sizeof(char) * stringStellen);

if (ret == NULL)
return NULL;

ret[stringStellen - 1] = '\0'; /* String Terminierung */

if (basis == 1) {
if (zahl != 0) {
for (size_t i = 0; i < stringStellen - 1; i++) {
ret[i] = '1';
}
} else
ret[0] = 0;
return ret;
}

size_t tmp = zahl;
unsigned short ziffer;

for (size_t i = 1; i < stringStellen; i++) {

ziffer = tmp % basis;
switch (ziffer) {
case 0:
ret[stringStellen - 1 - i] = '0';
break;
case 1:
ret[stringStellen - 1 - i] = '1';
break;
case 2:
ret[stringStellen - 1 - i] = '2';
break;
case 3:
ret[stringStellen - 1 - i] = '3';
break;
case 4:
ret[stringStellen - 1 - i] = '4';
break;
case 5:
ret[stringStellen - 1 - i] = '5';
break;
case 6:
ret[stringStellen - 1 - i] = '6';
break;
case 7:
ret[stringStellen - 1 - i] = '7';
break;
case 8:
ret[stringStellen - 1 - i] = '8';
break;
case 9:
ret[stringStellen - 1 - i] = '9';
break;
case 10:
ret[stringStellen - 1 - i] = 'A';
break;
case 11:
ret[stringStellen - 1 - i] = 'B';
break;
case 12:
ret[stringStellen - 1 - i] = 'C';
break;
case 13:
ret[stringStellen - 1 - i] = 'D';
break;
case 14:
ret[stringStellen - 1 - i] = 'E';
break;
case 15:
ret[stringStellen - 1 - i] = 'F';
break;
case 16:
ret[stringStellen - 1 - i] = 'G';
break;
case 17:
ret[stringStellen - 1 - i] = 'H';
break;
case 18:
ret[stringStellen - 1 - i] = 'I';
break;
case 19:
ret[stringStellen - 1 - i] = 'J';
break;

case 20:
ret[stringStellen - 1 - i] = 'K';
break;
case 21:
ret[stringStellen - 1 - i] = 'L';
break;
case 22:
ret[stringStellen - 1 - i] = 'M';
break;
case 23:
ret[stringStellen - 1 - i] = 'N';
break;
case 24:
ret[stringStellen - 1 - i] = 'O';
break;
case 25:
ret[stringStellen - 1 - i] = 'P';
break;
case 26:
ret[stringStellen - 1 - i] = 'Q';
break;
case 27:
ret[stringStellen - 1 - i] = 'R';
break;
case 28:
ret[stringStellen - 1 - i] = 'S';
break;
case 29:
ret[stringStellen - 1 - i] = 'T';
break;
case 30:
ret[stringStellen - 1 - i] = 'U';
break;
case 31:
ret[stringStellen - 1 - i] = 'V';
break;
case 32:
ret[stringStellen - 1 - i] = 'W';
break;
case 33:
ret[stringStellen - 1 - i] = 'X';
break;
case 34:
ret[stringStellen - 1 - i] = 'Y';
break;
case 35:
ret[stringStellen - 1 - i] = 'Z';
break;

}

tmp = tmp / basis;

}

return ret;
}

void test() {

printf("%d ", zaehleStellen(10, 1));

char * s = size_t2string(5, 1);

printf("%s ", s);


printf("%s ", size_t2string(5, 1)); /* ********** */

if (s)
free(s);

}

int main(int argc, char* argv[], char **umgebung) {
test();
return 0;
}
 

Lesen sie die antworten

#1 Claus Reibenstein
15/03/2010 - 15:10 | Warnen spam
Robert Hartmann schrieb:

Ich habe mich an einem size_t nach string Konverter
versucht, also einem Konverter der zu einem size_t
die passende Null-terminierte Zeichenkette als char*
zurückliefert.

Ganz glücklich bin ich damit noch nicht,
denn durch die Zeile in test() markiert mit /* ********** */
entsteht eine dynamische Speicherbelegung,
die man nicht mehr frei geben kann, oder?



Das ist richtig. Deswegen solltest Du das Ergebnis nicht direkt
verwenden, sondern - wie Du es ja außerdem ebenfalls gemacht hast - in
einer lokalen Variablen speichern und dann mit free() freigeben.

Kann man es noch irgendwie geschickter machen?



Oh ja. Vor allem diesen Block:

switch (ziffer) {
case 0:
ret[stringStellen - 1 - i] = '0';
break;
case 1:
ret[stringStellen - 1 - i] = '1';
break;
[...]
case 35:
ret[stringStellen - 1 - i] = 'Z';
break;

}



Da Dein "ziffer" garantiert im Bereich 0 bis 35 liegt, geht das viel
einfacher:

ret[stringStellen - 1 - i] "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[ziffer];

Diese wilde Indexberechnung kannst Du auch noch eliminieren, wenn Du
mehr mit Pointern arbeitest.

Gruß. Claus

Ähnliche fragen