2017-01-10 5 views
-3

安定した第2次元の2Dストリングアレイを動的に作成する最も簡単な方法は誰にも分かりますか?いくつかの文字列を含むtxtファイルがあり、このtxtを配列に転送したいと考えています。だから、最初の次元にはtxt行番号を、2番目の次元には文字列自体を関連づけたい。二次元は(TXT内のすべての行は、特定の構文を持っているので、安定している)すべての行の文字数であるだから、私はTXTにしている場合:2Dダイナミックストリングアレイを作成する

hello how (newline) 
are youuu 

*(私が書いたyouuu私が言ったようので、 、すべての行に同じ文字数があります)。

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

http://stackoverflow.com/questions/3536153/c -dynamically-growing-array – Jay

+2

2D配列を動的に割り当てる方法やサイズを変更する方法は不思議ですか? 'char(* arr)[CHARS_PER_LINE] = malloc(sizeof(* arr)* NUM_LINES);'多分? – Dmitri

+0

あなたの例では、最初の行に "(改行)"がありますが、2番目の行にはありません。それは意図的なものか、見落としなのか、それとも何ですか? – chux

答えて

2

非数字キーがCで許可されていないあなたは数字のみで動作する言語でいくつかのPHPとJavaScriptのナンセンスをやろうとしている:

は、私のような何かをしたいです。

しかし、Cでは地獄には常に2つの道があります。

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


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

あなたは、文字列の長さがわかっている場合は、あなたが持っているどのように多くの、あなたは、この

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

のような配列にアクセスすることができ、この

char strings[numLines][strLen+1]; 

のようなアレイを構成することができますあらかじめ分かっていない場合は、ポインタ配列へのポインタが必要です。そして、mallocを使って、配列が大きくなるにつれてスペースを割り当てます。

+1

もちろん、私の悪い – aggaton

+1

おそらく 'size_t strLen = foo(); char(* strings)[strLen + 1] = malloc(sizeof * arr * numLines); '? – chux

1

ダイナミック C言語では、[c] [m] allocのいずれかを使用して文字列用のメモリを作成する必要があります。 2Dは、配列charの配列を意味します。あなたは文字列と必要な最長の文字列の数を知っていると仮定すると、以下は、それらを格納するメモリを作成します。

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; 
} 

以下は、上記で作成したメモリ解放されます。これらは、することができ

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

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

それぞれ20個の文字を含むことができる10個の配列とNULLを与えます。 (maxStrLenの後の+ 1は、NULLに余分なスペースを提供します)。

+0

技術的には2D配列でも配列の配列でもない... 1D配列のポインタで、それぞれが別々に割り当てられた 'char'の1D配列を指しています。実際の2D配列も可能ですが、異なっています。 – Dmitri

+0

@Dmitri - 技術的に正しいです。しかし、Cでは、動的に作成する必要がある場合には、概念的にはそれが得られるほど近くにあります。 – ryyker

+0

'char(* arr)[21] = calloc(10、sizeof(* arr));'? – Dmitri

1

あなたは、配列の行として、ファイルの各行を保存charの2次元配列を使用する場合:あなたは、フロントまで持っているどのように多くの行がわからない場合

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

、あなたをいくつかのメモリ管理が必要です。まず、最初のエクステントを割り当てる必要があります。

#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 

ファイルを読み込むときに、配列に空きがあることを確認します。そうでない場合は、realloc呼び出しを使用して配列を拡張する必要がありますが、これは潜在的に高価な操作です。一般的な手法は、配列を拡張するたびに配列のサイズを2倍にすることです。これにより、realloc呼び出しの総数が最小限に抑えられます。もう1行必要であるため配列サイズを2倍にすると内部的な断片化が起こる危険がありますが、それは恐らく解析できるものです:

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); 
} 
関連する問題