2017-01-10 4 views
-3

Kann mir jemand die einfachste Möglichkeit erklären, dynamisch ein 2D-String-Array mit stabiler zweiter Dimension zu erstellen? Ich habe eine TXT-Datei mit einigen Strings darin und ich möchte diesen TXT in ein Array übertragen. Also möchte ich die txt Zeilennummer mit der ersten Dimension und die Zeichenfolge selbst mit der zweiten Dimension verbinden. Die zweite Dimension ist die Anzahl der Zeichen in jeder Zeile (die stabil ist, weil jede Zeile in der txt eine bestimmte Syntax) Also, wenn ich in meiner txt:Erstellen Sie ein dynamisches 2D-String-Array

hello how (newline) 
are youuu 

* (Ich schreibe youuu denn wie gesagt , jede Zeile hat die gleiche Anzahl von Zeichen).

Ich möchte so etwas wie:

array[0]["hello how"], 
array[1]["are youuu"] 
+0

Blick auf http://stackoverflow.com/questions/3536153/c -dynamisch wachsendes Array – Jay

+2

Fragen Sie sich nur, wie man ein 2D-Array dynamisch zuordnet oder wie man es skaliert? So etwas wie 'char (* arr) [CHARS_PER_LINE] = malloc (sizeof (* arr) * NUM_LINES);' vielleicht? – Dmitri

+0

In Ihrem Beispiel hat die erste Zeile ein "(Newline)", aber das zweite nicht. Ist das absichtlich, ein Versehen oder was? – chux

Antwort

2

Nicht numerische Tasten sind in C nicht erlaubt Sie versuchen, einige PHP und JavaScript Unsinn in einer Sprache zu tun, die nur mit Zahlen arbeitet.

Aber mit C gibt es immer 2 Straßen zur Hölle.

char *lookup_key(int index, char *key) { ... } 


printf(lookup_key(0, "hello how")); 
2

Wenn Sie wissen, die Länge der Saiten und wie viele Sie haben, können Sie das Array wie diese

char strings[numLines][strLen+1]; 

Sie können dann das Array zugreifen konfigurieren wie diese

strcpy(strings[1], "test2"); 

Wenn Sie vorher nichts wissen, benötigen Sie einen Zeiger auf Zeiger-Array und verwenden Sie dann malloc, um Speicherplatz zuzuweisen, wenn das Array wächst, wenn Sie fertig sind.

+1

Natürlich, mein schlechtes – aggaton

+1

Vielleicht 'size_t strLen = foo(); char (* Zeichenfolgen) [strLen + 1] = malloc (sizeof * arr * numLines); '? – chux

1

dynamisch in C bedeutet, dass Sie eine der [c] [m] Alloc verwenden müssen, um Speicher für Ihre Zeichenfolgen zu erstellen. Und 2D impliziert ein Array von char Arrays. Angenommen, Sie wissen, die Anzahl der Strings und die längste Zeichenfolge benötigt wird, wird die folgende Speicher erstellen, sie enthalten:

char ** Create2DStr(ssize_t numStrings, ssize_t maxStrLen) 
{ 
    int i; 
    char **a = {0}; 
    a = calloc(numStrings, sizeof(char *)); 
    for(i=0;i<numStrings; i++) 
    { 
     a[i] = calloc(maxStrLen + 1, 1); 
    } 
    return a; 
} 

Im Folgenden wird die oben erstellt Speicher frei: Diese

void free2DStr(char ** a, ssize_t numStrings) 
{ 
    int i; 
    for(i=0;i<numStrings; i++) 
    { 
     if(a[i]) free(a[i]); 
    } 
    free(a); 
} 

sein kann genannt wie folgt:

... 
char **strArray = {0}; 
strArray = Create2DStr(10, 20); 
//Use strArray... 
free2DStr(10); 

Geben Sie 10 Arrays, jede in der Lage, 20 char, plus ein NULL enthalten. (Die + 1 nach maxStrLen bietet den zusätzlichen Platz für die NULL).

+0

Technisch gesehen ist das kein 2D-Array oder ein Array von Arrays ... es ist ein 1D-Array von Zeigern, von denen jeder auf ein separat zugewiesenes 1D-Array von 'char' zeigt. Ein tatsächliches 2D-Array ist ebenfalls möglich, aber anders. – Dmitri

+0

@Dmitri - technisch sind Sie richtig. Aber in C ist es konzeptionell so nah wie möglich, wenn es dynamisch erstellt werden muss. – ryyker

+0

Was ist mit 'char (* arr) [21] = Calloc (10, sizeof (* arr));'? – Dmitri

1

Wenn Sie jede Zeile der Datei als eine Zeile in dem Array zu speichern, verwenden Sie einen 2D-Array von char:

char fileContents[NUM_LINES][LINE_LENGTH + 1]; // +1 for zero terminator 

Wenn Sie nicht wissen, wie viele Zeilen, die Sie haben, dich vorne Ich brauche etwas Speicherverwaltung.Zuerst müssen Sie einen ersten Umfang zuzuordnen:

#define INITIAL_EXTENT 20 // or some good starting point 

char (*fileContents)[LINE_LENGTH + 1] = malloc(sizeof *fileContents * INITIAL_EXTENT); 
if (!fileContents) 
{ 
    // malloc failed; fatal error 
    fprintf(stderr, "FATAL: could not allocate memory for array\n"); 
    exit(EXIT_FAILURE); 
} 
size_t numRows = INITIAL_EXTENT; // number of rows in array 
size_t rowsRead = 0;    // number of rows containing data 

Wie Sie aus der Datei lesen, werden Sie überprüfen, um sicherzustellen, dass Sie Zimmer im Array; Wenn Sie dies nicht tun, müssen Sie das Array mit einem realloc Aufruf erweitern, was eine potenziell teure Operation ist. Eine übliche Technik besteht darin, die Größe des Arrays bei jeder Erweiterung zu verdoppeln - das minimiert die Gesamtzahl der Aufrufe realloc. Das Risiko ist einige interne Fragmentierung, wenn Sie die Array-Größe verdoppeln, weil Sie nur eine weitere Zeile benötigen, aber das ist wahrscheinlich etwas, das Sie analysieren um können:

char tmpBuf[LINE_LENGTH + 2]; // account for newline in input buffer 

while (fgets(tmpBuf, sizeof tmpBuf, inputFile)) 
{ 
    /** 
    * Check to see if you have any room left in your array; if not, 
    * you'll need to extend it. You'll probably want to factor this 
    * into its own function. 
    */ 
    if (rowsRead == numRows) 
    { 
    /** 
    * Use a temporary variable for the result of realloc in case of failure 
    */ 
    char (*tmp)[LINE_LENGTH + 1] = 
     realloc(fileContents, sizeof *fileContents * (2 * numRows)); 

    if (!tmp) 
    { 
     /** 
     * realloc failed - we couldn't extend the array any more. 
     * Break out of the loop. 
     */ 
     fprintf(stderr, "ERROR: could not extend fileContents array - breaking out of loop\n"); 
     break; 
    } 
    /** 
    * Otherwise, set fileContents to point to the new, extended buffer 
    * and update the number of rows. 
    */ 
    fileContents = tmp; 
    numRows *= 2; 
    } 

    // strip the newline from the input buffer 
    char *newline = strchr(tmpBuf, '\n'); 
    if (newline) 
    *newline = 0; 

    strcpy(fileContents[rowsRead++], tmpBuf); 
} 
Verwandte Themen