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.
Wie konvertiert man ein int in einen String in C?
Benutzer1063999
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önnenmalloc(sizeof(char)*(int)log10(num))
– Hauleth
24. November 2011 um 13:25 Uhr
-
@Hauleth Oder sogar +2, wenn man das bedenkt
(int)log10(42)
ist1
.– 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 alloclength+1
Zeichen für die Zeichenfolge.– Benutzer2622016
28. September 2015 um 6:10 Uhr
Alexander Galkin
BEARBEITEN: Wie im Kommentar erwähnt, itoa()
ist kein Standard, verwenden Sie also besser den in der konkurrierenden Antwort vorgeschlagenen sprintf () -Ansatz!
Sie können verwenden 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, müssen Sie vorher keinen Wert konvertieren. 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
-
@PaulR Das wusste ich jetzt nicht! Danke für die Klarstellung.
– Christian Rau
24. November 2011 um 13:31 Uhr
-
@PaulR Danke, das wusste ich nicht!
– Alexander Galkin
24. November 2011 um 13:32 Uhr
-
@SeanRamey Das
itoa()
leidet unter dem gleichen Pufferüberlaufpotential wiegets()
.– 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
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
#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
Das ist alt, aber 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?
– DADi590
5. Februar um 15:39 Uhr
etw
Wenn Sie GCC verwenden, können Sie die GNU-Erweiterung asprintf-Funktion verwenden.
char* str;
asprintf (&str, "%i", 12313);
free(str);
-
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?
– DADi590
5. Februar 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
-
Hey Chux, weißt du, ob es eine Möglichkeit gibt, die interne glibc-Implementierung offenzulegen? sourceware.org/git/?p=glibc.git;a=blob;f=stdio-common/…
– Ciro Santilli OurBigBook.com
1. September 2018 um 12:03 Uhr
-
@CiroSantilli新疆改造中心六四事件法轮功 Ich bin mit der internen glibc-Implementierung nicht vertraut.
– chux – Wiedereinsetzung von Monica
1. September 2018 um 15:52 Uhr
-
Sollte es nicht sein
'0' + x % 10
Anstatt von'0' - x % 10
(Um eine binäre Ganzzahl zwischen Dezimal 0 und Dezimal 9 der binären ASCII-Codierung zuzuordnen)?– étale-Kohomologie
1. Februar um 19:55 Uhr
-
@étale-Kohomologie
x%10
hat den Wert von [-9 … 0] wiex <= 0
nicht 0 bis 9.'0' - x % 10
ist richtig. Verwenden der negativen Seite vonint
vermeidet UB voni = -i;
Wenni == INT_MIN
was dieser Code niemals tut.– chux – Wiedereinsetzung von Monica
1. Februar um 19:58 Uhr
-
@étale-cohomology UB –> Undefiniertes Verhalten. Verneinung
INT_MIN
ist U.B.– chux – Wiedereinsetzung von Monica
1. Februar um 22:14 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
mögliches Duplikat von Converting in string in c
– nawfal
17. Juli 2014 um 7:18 Uhr