Erstellt ein Char-Array mit einer Ganzzahl, die Ziffern als Größe verwendet

7

Ich versuche, ein char-Array in C zu erstellen, um es mit den Ziffern eines int zu füllen, aber der int kann aus einer beliebigen Anzahl von Ziffern bestehen.

Ich verwende eine erstellte Funktion namens getDigits(int num) , die eine Anzahl von Ziffern zurückgibt, die int hat.

%Vor%

, aber wenn ich mit gcc kompiliere, gibt es zurück:

error: variable-sized object may not be initialized

Ich habe alles versucht. Wenn ich es als char fileSizeStr[5] = ""; deklariere, funktioniert es. Ich kann sehen, dass das Problem steigt, wenn ich versuche, die Puffergröße dynamisch zu deklarieren, aber ich würde wirklich gerne wissen, ob dies ein Weg ist, dies zu erreichen.

    
anairinac 07.06.2013, 00:25
quelle

5 Antworten

16

Das Problem ist genau so, wie Ihr Compiler es Ihnen sagt; 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 sind von den sinnvollsten (IMHO) zu den am wenigsten sinnvollen (mit malloc ) für die Zuweisung von Speicher für Dezimalziffernfolgen, die Zahlen darstellen, angeordnet.

Ich schlage vor, mit demselben Trick zu bestimmen, wie viele Bytes zum Speichern eines int -Werts als Dezimalziffern erforderlich sind, wie Sie für oktal verwenden würden: Teilen Sie die Gesamtzahl der Bits in int durch 3 und addieren Sie für jedes Zeichen und NULL Kündigung. digit_count könnte als ein Präprozessor-Makro wie folgt geschrieben werden:

%Vor%

Wie Sie sehen, ist ein großer Vorteil hier, dass digit_count für jede Art von Ganzzahl ohne Änderung verwendet werden kann: char , short , int , long , long long und Entsprechende unsigned -Typen.

Ein kleiner Nachteil im Vergleich ist, dass Sie ein paar Bytes Speicher verschwenden, besonders für kleine Werte wie 1 . In vielen Fällen gleicht die Einfachheit dieser Lösung dies aus; Der Code, der zum Zählen der Dezimalziffern zur Laufzeit benötigt wird, belegt mehr Speicherplatz als hier verschwendet wird.

Wenn Sie bereit sind, die Einfachheit und generischen Eigenschaften des obigen Codes wegzuwerfen, und Sie wirklich die Anzahl der Dezimalstellen zählen möchten, gilt Zacks Rat: Entfernen Sie die Initialisierung. Hier ist ein Beispiel:

%Vor%

Als Reaktion auf die malloc -Empfehlungen: Der am wenigsten schreckliche Weg zur Lösung dieses Problems besteht darin, unnötigen Code zu vermeiden (zB Aufrufe an malloc und später an 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 zu verwenden, tun Sie es jedoch am wenigsten schrecklich. Vermeiden Sie Typumwandlungen auf dem Rückgabewert von malloc und Multiplikationen von sizeof (char) (was immer 1 ist). Der folgende Code ist ein Beispiel. Verwenden Sie eine der obigen Methoden, um die Länge zu berechnen:

%Vor%

... und vergiss nicht free(buffer); , wenn du damit fertig bist.

    
Sebivor 07.06.2013, 02:45
quelle
5

versuche etwas wie:

%Vor%

malloc und calloc werden für die dynamische Zuordnung verwendet.

    
Rafael Azevedo 07.06.2013 00:32
quelle
3

unten kann helfen

%Vor%     
NonStatic 07.06.2013 00:34
quelle
3

Für mein Geld gibt es eine Lösung, die unerwähnt geblieben ist, die aber tatsächlich einfacher ist als alle anderen. Es gibt eine kombinierte Allokationsversion von sprintf namens "asprintf", die unter Linux und den meisten BSD-Varianten verfügbar ist. Es bestimmt die erforderliche Größe, mallocs den Speicher und gibt die gefüllte Zeichenfolge in das erste Argument zurück.

%Vor%

Die Verwendung eines Stack-zugewiesenen Arrays beseitigt zwar die Notwendigkeit für das Free, aber das macht es völlig überflüssig, die Größe jemals separat zu berechnen.

    
njustn 14.06.2013 17:28
quelle
2

Sie müssen malloc verwenden, um eine dynamische Menge an Speicher zuzuweisen.

Die Initialisierung Ihrer Methode ist nur erlaubt, wenn die Größe zur Kompilierzeit bekannt ist.

    
John 07.06.2013 00:29
quelle

Tags und Links