Wie konvertiert man ein int in einen String in C?

Lesezeit: 8 Minuten

Benutzeravatar von user1063999
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.

  • 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

Benutzeravatar von cnicutar
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

Benutzeravatar von Alexander Galkin
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 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

Benutzeravatar von user2622016
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

Benutzeravatar von David C. Rankin
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;
}

Benutzeravatar von catfood
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

sths Benutzeravatar
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] wie x <= 0nicht 0 bis 9. '0' - x % 10 ist richtig. Verwenden der negativen Seite von int vermeidet UB von i = -i; Wenn i == INT_MINwas 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


1427360cookie-checkWie konvertiert man ein int in einen String in C?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy