Wie konvertiert man ein int
(Ganzzahl) in eine Zeichenfolge?
Ich versuche, eine Funktion zu erstellen, die die Daten von a konvertiert struct
in eine Zeichenfolge, um sie in einer Datei zu speichern.
Benutzer1063999
Wie konvertiert man ein int
(Ganzzahl) in eine Zeichenfolge?
Ich versuche, eine Funktion zu erstellen, die die Daten von a konvertiert struct
in eine Zeichenfolge, um sie in einer Datei zu speichern.
Cnicutar
Sie können verwenden sprintf
zu tun, oder vielleicht snprintf
Wenn du es hast:
char str[ENOUGH];
sprintf(str, "%d", 42);
Wo die Anzahl der Zeichen (plus abschließendes Zeichen) in der str
kann berechnet werden mit:
(int)((ceil(log10(num))+1)*sizeof(char))
Allerdings tat ENOUGH
ist genug, womit wir es schaffen können malloc(sizeof(char)*(int)log10(num))
– Hauleth
24. November 2011 um 13:25 Uhr
@Hauleth Oder sogar +2, wenn man das bedenkt (int)log10(42)
Ist 1
.
– Christian Rau
24. November 2011 um 13:34 Uhr
Oder Sie können es zur Kompilierzeit berechnen: #define ENOUGH ((CHAR_BIT * sizeof(int) - 1) / 3 + 2)
– Café
25. November 2011 um 0:31 Uhr
@hauleth Immer noch +2 statt +1, sogar mit ceil: ceil(log(100)) = 2,0, nicht 3. Also +1 für die genauen Potenzen von 10 und ein weiteres +1 für die Beendigung von null.
– noch nicht
12. Februar 2015 um 17:23 Uhr
Sie berücksichtigen kein Minuszeichen und Gebietsschema: Tausendertrennzeichen und Gruppierung. Bitte machen Sie es so: verwenden int length = snprintf(NULL, 0,"%d",42);
um Länge zu bekommen, und dann alloc length+1
Zeichen für die Zeichenfolge.
– Benutzer2622016
28. September 2015 um 6:10 Uhr
Alexander Galkin
Wie in einem Kommentar erwähnt, itoa()
ist kein Standard, verwenden Sie also besser den in der konkurrierenden Antwort vorgeschlagenen sprintf () -Ansatz!
Du kannst den … benutzen itoa()
Funktion zu Konvertieren Ihren ganzzahligen Wert in eine Zeichenfolge.
Hier ist ein Beispiel:
int num = 321;
char snum[5];
// Convert 123 to string [buf]
itoa(num, snum, 10);
// Print our string
printf("%s\n", snum);
Wenn Sie Ihre Struktur in eine Datei ausgeben möchten, brauchen Sie vorher keinen Wert umzuwandeln. Sie können einfach die verwenden printf-Formatspezifikation um anzugeben, wie Sie Ihre Werte ausgeben und einen der Operatoren von verwenden printf-Familie um Ihre Daten auszugeben.
itoa
ist kein Standard – siehe z. B. stackoverflow.com/questions/190229/…
– PaulR
24. November 2011 um 13:26 Uhr
@SeanRamey Das itoa()
leidet unter dem gleichen Pufferüberlaufpotential wie gets()
.
– chux – Wiedereinsetzung von Monica
1. September 2018 um 15:55 Uhr
itoa ist nicht in C verfügbar (mindestens C99). es ist in C++ besser verfügbar
– Motti Schoner
27. März 2019 um 6:43 Uhr
Wie bekommt man das ohne sprintf
oder itoa
? Möglicherweise beim Schreiben einer benutzerdefinierten Standardbibliothek?
– SS Anne
30. März 2019 um 2:28 Uhr
Warum haben Sie das Argument als 10 übergeben?
– Rasathurai Karan
8. September 2021 um 11:53 Uhr
Benutzer2622016
Die kurze Antwort lautet:
snprintf( str, size, "%d", x );
Je länger ist: zuerst müssen Sie die ausreichende Größe herausfinden. snprintf
sagt dir Länge wenn du es mit nennst NULL, 0
als erste Parameter:
snprintf( NULL, 0, "%d", x );
Ordnen Sie dem Nullterminator ein Zeichen mehr zu.
#include <stdio.h>
#include <stdlib.h>
int x = -42;
int length = snprintf( NULL, 0, "%d", x );
char* str = malloc( length + 1 );
snprintf( str, length + 1, "%d", x );
...
free(str);
Wenn das für jeden Format-String funktioniert, können Sie Float oder Double in einen String umwandeln, indem Sie verwenden "%g"
können Sie mit int in hex umwandeln "%x"
usw.
#include
– Benutzer1821961
2. November 2017 um 19:29 Uhr
@ user1821961 Danke, es sollte wirklich erwähnt werden, dass diese Header-Dateien enthalten sein müssen.
– byxor
27. April 2018 um 19:49 Uhr
Hey, ich weiß, das ist eine super alte Antwort, aber warum “+1” in Malloc? ist es für die ‘\0’ ?
– Fliegender_Wal
3. April 2021 um 14:34 Uhr
Ja, +1 steht für ‘\0’. snprintf gibt length ohne das abschließende Nullzeichen zurück, aber im zweiten Parameter erwartet es length mit abschließendem Nullzeichen, also length + 1.
– Benutzer2622016
3. April 2021 um 19:33 Uhr
@jinkwon Ja stackoverflow.com/a/35036037/330457
– Jinkwon
23. September 2021 um 14:22 Uhr
David C. Rankin
Nachdem ich mir verschiedene Versionen von itoa für gcc angesehen habe, ist die flexibelste Version, die ich gefunden habe und die in der Lage ist, Konvertierungen in Binär-, Dezimal- und Hexadezimalzahlen, sowohl positiv als auch negativ, zu handhaben, die vierte Version, die unter gefunden wird http://www.strudel.org.uk/itoa/. Während sprintf
/snprintf
haben Vorteile, sie verarbeiten keine negativen Zahlen für etwas anderes als die Dezimalumwandlung. Da der obige Link entweder offline oder nicht mehr aktiv ist, habe ich ihre 4. Version unten eingefügt:
/**
* C++ version 0.4 char* style "itoa":
* Written by Lukás Chmela
* Released under GPLv3.
*/
char* itoa(int value, char* result, int base) {
// check that the base if valid
if (base < 2 || base > 36) { *result="\0"; return result; }
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while ( value );
// Apply negative sign
if (tmp_value < 0) *ptr++ = '-';
*ptr-- = '\0';
while(ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return result;
}
Katzenfutter
Hier ist ein anderer Weg.
#include <stdio.h>
#define atoa(x) #x
int main(int argc, char *argv[])
{
char *string = atoa(1234567890);
printf("%s\n", string);
return 0;
}
Funktioniert nur für Konstanten, nicht für Variablen.
– Nackt
3. Februar 2014 um 22:06 Uhr
Warum funktioniert es nicht, wenn ich dort ein Makro einfüge …? Ist es nicht auch eine Konstante?
– Edu590
5. Februar 2022 um 15:39 Uhr
Das Konvertieren von irgendetwas in einen String sollte entweder 1) den resultierenden String zuweisen oder 2) in a übergeben char *
Reiseziel und Größe. Beispielcode unten:
Beides funktioniert für alle int
einschließlich INT_MIN
. Sie bieten eine konsistente Ausgabe im Gegensatz zu snprintf()
was vom aktuellen Gebietsschema abhängt.
Methode 1: Retouren NULL
auf Speichermangel.
#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: Es kehrt zurück 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;
}
[Edit] als Anfrage von @Alter Mann
(CHAR_BIT*sizeof(int_type)-1)*10/33+3
ist mindestens die maximale Anzahl von char
erforderlich, um den Typ einer vorzeichenbehafteten Ganzzahl als Zeichenfolge zu codieren, die aus einem optionalen negativen Vorzeichen, Ziffern und einem Nullzeichen besteht.
Die Anzahl der Bits ohne Vorzeichen in einer vorzeichenbehafteten Ganzzahl ist nicht größer als CHAR_BIT*sizeof(int_type)-1
. Eine Basis-10-Darstellung von a 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. Andere Brüche könnten verwendet werden, wie 28/93.
Methode 3: Wenn man am Rand leben möchte und Pufferüberlauf kein Problem darstellt, folgt eine einfache C99- oder neuere Lösung, die behandelt 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));
}
Beispielausgabe
0
1
-1
12345
2147483646
2147483647
-2147483647
-2147483648
Funktioniert nur für Konstanten, nicht für Variablen.
– Nackt
3. Februar 2014 um 22:06 Uhr
Warum funktioniert es nicht, wenn ich dort ein Makro einfüge …? Ist es nicht auch eine Konstante?
– Edu590
5. Februar 2022 um 15:39 Uhr
Peter Mortensen
Wenn Sie GCC verwenden, können Sie die GNU-Erweiterung verwenden asprintf Funktion.
char* str;
asprintf(&str, "%i", 12313);
free(str);
Eine Begründung Vielleicht: “Die sprintf-Funktion kann gefährlich sein, da sie möglicherweise mehr Zeichen ausgeben kann, als in die Zuordnungsgröße der Zeichenfolge s passen … Um dieses Problem zu vermeiden, können Sie verwenden snprintf
oder asprintf
“
– Peter Mortensen
6. Februar um 16:43 Uhr
printf
oder einer seiner Cousins sollte es tun– pmg
24. November 2011 um 13:21 Uhr
mögliches Duplikat von Wo ist die Itoa-Funktion in Linux?
– PaulR
24. November 2011 um 13:27 Uhr
Sie können auch sehen wollen diese häufig gestellten Fragen zur Serialisierung, und vielleicht die folgenden Fragen, die sich auf die Serialisierung in C beziehen: (a), (b), (c), um Ihre eigentliche Absicht zu erreichen.
– muuuuh
24. November 2011 um 13:35 Uhr
Mein übliches semantisches Ärgernis hier. Sie möchten nichts umwandeln; Sie möchten eine Zeichenfolge erhalten, die eine (Basis 10?) Darstellung des Werts von enthält
int
. Ja ich weiß. Es ist eine sehr häufige Abkürzung, aber es nervt mich immer noch.– dmckee — Ex-Moderator-Kätzchen
24. Mai 2014 um 2:41 Uhr
Können Sie bitte die derzeit akzeptierte Antwort aufheben und die am höchsten bewertete akzeptieren?
itoa
ist nicht standardisiert, alsosnprintf
ist tragbarer.– SS Anne
24. Januar 2020 um 22:43 Uhr