Das Problem ist, helfen, genau wie Ihr Compiler sagt Ihnen; Sie dürfen keine VLAs initialisieren. Zack gab eine offensichtliche Lösung in den Kommentaren: Entfernen Sie die Initialisierung. In dieser Antwort finden Sie Arbeitsbeispiele, von denen einige eine Initialisierung erlauben und andere nicht. Mehr dazu finden Sie in Kommentaren. Die folgenden Beispiele werden von den meisten sinnvollen (IMHO) zu den am wenigsten sinnvollen (mit der Verwendung von malloc
) Ordnungen zum Zuweisen von Speicher für Dezimalziffernfolgen, die Zahlen darstellen, angeordnet.
Ich schlage vor, den gleichen Trick, um zu bestimmen mit, wie viele Bytes notwendig sind, um einen int
Wert als Dezimalstellen zu speichern, wie Sie für Oktal verwenden würde: Teilen Sie die Gesamtzahl der Bits in einem int
von 3 und fügen Sie für jedes Zeichen und NULL Kündigung. digit_count
als Präprozessormakro wie so geschrieben werden:
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#define digit_count(num) (1 /* sign */ \
+ sizeof (num) * CHAR_BIT/3 /* digits */ \
+ (sizeof (num) * CHAR_BIT % 3 > 0)/* remaining digit */ \
+ 1) /* NUL terminator */
int main(void) {
short short_number = -32767;
int int_number = 32767;
char short_buffer[digit_count(short_number)] = { 0 }; /* initialisation permitted here */
char int_buffer[digit_count(int_number)];
sprintf(short_buffer, "%d", short_number);
sprintf(int_buffer, "%d", int_number);
}
Wie Sie sehen können, ein leistungsfähiger Vorteil hierbei ist, dass digit_count
kann für jede Art von Integer ohne Modifikation verwendet werden: char
, short
, int
, long long
long
und die entsprechenden unsigned
Typen.
Ein kleiner Nachteil im Vergleich ist, dass Sie ein paar Byte Speicherplatz verschwenden, vor allem für kleine Werte wie 1
. In vielen Fällen gleicht die Einfachheit dieser Lösung dies aus; Der Code benötigt, um die Dezimalstellen zur Laufzeit zu zählen, wird mehr Platz im Speicher belegen als hier verschwendet wird.
Wenn Sie bereit sind, die Einfachheit und die generische Qualitäten des obigen Codes wegzuwerfen, und Sie wirklich wollen, um die Anzahl der Dezimalstellen zählen, Zacks Rat gilt: die Initialisierung entfernen.Hier ein Beispiel:
#include <stddef.h>
#include <stdio.h>
size_t digit_count(int num) {
return snprintf(NULL, 0, "%d", num) + 1;
}
int main(void) {
int number = 32767;
char buffer[digit_count(number)]; /* Erroneous initialisation removed as per Zacks advice */
sprintf(buffer, "%d", number);
}
Als Reaktion auf die malloc
Empfehlungen: Die am wenigsten schreckliche Art und Weise, dieses Problem zu lösen, ist nicht notwendig, den Code zu vermeiden (zB Anrufe zu malloc
und später free
.). Wenn Sie das Objekt nicht von einer Funktion zurückgeben müssen, verwenden Sie nicht malloc
! Andernfalls sollten Sie in einem vom Aufrufer bereitgestellten Puffer speichern (über Argumente), damit der Anrufer auswählen kann, welcher Speichertyp verwendet werden soll. Es ist sehr selten, dass dies keine geeignete Alternative zur Verwendung von malloc
ist.
Wenn Sie sich dafür entscheiden, malloc
und free
dafür zu verwenden, tun Sie es jedoch die am wenigsten schreckliche Weise. Vermeiden Sie Typumwandlungen auf dem Rückgabewert malloc
und Multiplikationen von sizeof (char)
(die immer 1 ist). Der folgende Code ist ein Beispiel. Verwenden Sie eine der oben genannten Methoden, um die Länge zu berechnen:
char *buffer = malloc(digit_count(number)); /* Initialisation of malloc bytes not possible */
sprintf(buffer, "%d", number);
... und vergessen Sie nicht zu free(buffer);
, wenn Sie mit ihm fertig sind.
malloc der Puffer. – Duck
Verwenden Sie den Compiler c99 oder verwenden Sie malloc – BLUEPIXY
Versuchen Sie, das '=" "zu entfernen. 'snprintf' ist es egal, was vorher in seinem Ausgabepuffer ist. – zwol