Wie konvertiert man eine int
(Ganzzahl) in eine Zeichenkette? Ich versuche, eine Funktion zu erstellen, die die Daten einer struct
in eine Zeichenkette, um sie in einer Datei zu speichern.
Antworten
Zu viele Anzeigen?Die Konvertierung von etwas in eine Zeichenkette sollte entweder 1) die resultierende Zeichenkette zuweisen oder 2) eine char *
Zielort und Größe. Beispielcode unten:
Beide arbeiten für alle int
einschließlich INT_MIN
. Sie liefern ein konsistentes Ergebnis im Gegensatz zu snprintf()
die vom aktuellen Gebietsschema abhängt.
Methode 1: Rückgaben NULL
bei Out-of-Memory.
#define INT_DECIMAL_STRING_SIZE(int_type) ((CHAR_BIT*sizeof(int_type)-1)*10/33+3)
char *int_to_string_alloc(int x) {
int i = x;
char buf[INT_DECIMAL_STRING_SIZE(int)];
char *p = &buf[sizeof buf] - 1;
*p = '\0';
if (i >= 0) {
i = -i;
}
do {
p--;
*p = (char) ('0' - i % 10);
i /= 10;
} while (i);
if (x < 0) {
p--;
*p = '-';
}
size_t len = (size_t) (&buf[sizeof buf] - p);
char *s = malloc(len);
if (s) {
memcpy(s, p, len);
}
return s;
}
Methode 2: Sie liefert NULL
wenn der Puffer zu klein war.
static char *int_to_string_helper(char *dest, size_t n, int x) {
if (n == 0) {
return NULL;
}
if (x <= -10) {
dest = int_to_string_helper(dest, n - 1, x / 10);
if (dest == NULL) return NULL;
}
*dest = (char) ('0' - x % 10);
return dest + 1;
}
char *int_to_string(char *dest, size_t n, int x) {
char *p = dest;
if (n == 0) {
return NULL;
}
n--;
if (x < 0) {
if (n == 0) return NULL;
n--;
*p++ = '-';
} else {
x = -x;
}
p = int_to_string_helper(p, n, x);
if (p == NULL) return NULL;
*p = 0;
return dest;
}
[Bearbeiten] auf Anfrage von @Alter Mann
(CHAR_BIT*sizeof(int_type)-1)*10/33+3
ist mindestens die maximale Anzahl von char
benötigt, um den Typ Some Signed Integer als String zu kodieren, der aus einem optionalen negativen Vorzeichen, Ziffern und einem Nullzeichen besteht.
Die Anzahl der nicht vorzeichenbehafteten Bits in einer vorzeichenbehafteten ganzen Zahl ist nicht höher als CHAR_BIT*sizeof(int_type)-1
. Eine Basis-10-Darstellung einer n
-Bit-Binärzahl dauert bis zu n*log10(2) + 1
Ziffern. 10/33
ist etwas mehr als log10(2)
. +1 für das Zeichen char
und +1 für das Nullzeichen. Es können auch andere Brüche wie 28/93 verwendet werden.
Methode 3: Wenn man am Rande leben will und ein Pufferüberlauf kein Thema ist, folgt eine einfache C99- oder spätere Lösung, die mit alle int
.
#include <limits.h>
#include <stdio.h>
static char *itoa_simple_helper(char *dest, int i) {
if (i <= -10) {
dest = itoa_simple_helper(dest, i/10);
}
*dest++ = '0' - i%10;
return dest;
}
char *itoa_simple(char *dest, int i) {
char *s = dest;
if (i < 0) {
*s++ = '-';
} else {
i = -i;
}
*itoa_simple_helper(s, i) = '\0';
return dest;
}
int main() {
char s[100];
puts(itoa_simple(s, 0));
puts(itoa_simple(s, 1));
puts(itoa_simple(s, -1));
puts(itoa_simple(s, 12345));
puts(itoa_simple(s, INT_MAX-1));
puts(itoa_simple(s, INT_MAX));
puts(itoa_simple(s, INT_MIN+1));
puts(itoa_simple(s, INT_MIN));
}
Beispielhafte Ausgabe
0
1
-1
12345
2147483646
2147483647
-2147483647
-2147483648
/*Function return size of string and convert signed *
*integer to ascii value and store them in array of *
*character with NULL at the end of the array */
int itoa(int value,char *ptr)
{
int count=0,temp;
if(ptr==NULL)
return 0;
if(value==0)
{
*ptr='0';
return 1;
}
if(value<0)
{
value*=(-1);
*ptr++='-';
count++;
}
for(temp=value;temp>0;temp/=10,ptr++);
*ptr='\0';
for(temp=value;temp>0;temp/=10)
{
*--ptr=temp%10+'0';
count++;
}
return count;
}