2

この関数でchar**リストにメモリを動的に割り当てるにはどうすればよいですか?

基本的に、このプログラムの考え方は、ファイルから単語のリストを読み取らなければならないということです。最大文字列または最大文字列長を想定することはできません。

私はCストリングで他のことをしなければなりませんが、それは私がうまくいくはずです。

ありがとう!

void readFileAndReplace(int argc, char** argv)
{
    FILE *myFile;
    char** list;
    char c;
    int wordLine = 0, counter = 0, i;
    int maxNumberOfChars = 0, numberOfLines = 0, numberOfChars = 0;

    myFile = fopen(argv[1], "r");

    if(!myFile)
    {
        printf("No such file or directory\n");
        exit(EXIT_FAILURE);
    }

    while((c = fgetc(myFile)) !=EOF)
    {
        numberOfChars++;
        if(c == '\n')
        {
            if(maxNumberOfChars < numberOfChars)
                maxNumberOfChars += numberOfChars + 1;

            numberOfLines++;
        }
    }

    list = malloc(sizeof(char*)*numberOfLines);

    for(i = 0; i < wordLine ; i++)
        list[i] = malloc(sizeof(char)*maxNumberOfChars);


    while((c = fgetc(myFile)) != EOF)
    {
        if(c == '\n' && counter > 0)
        {
            list[wordLine][counter] = '\0';
            wordLine++;
            counter = 0;
        }
        else if(c != '\n')
        {
            list[wordLine][counter] = c;
            counter++;
        }
    }
}
4

2 に答える 2

10

このようにしてください:

char** list; 

list = malloc(sizeof(char*)*number_of_row);
for(i=0;i<number_of_row; i++) 
  list[i] = malloc(sizeof(char)*number_of_col);  

さらに、メモリを動的に割り当てる場合。あなたは仕事が終わったようにそれを解放することになっています:

for(i=0;i<number_of_row; i++) 
  free(list[i] );
free(list);  

編集

質問を修正しました:

 int wordLine = 0, counter = 0, i;    

wordLinecounter0

このコードの前:

list = malloc(sizeof(char*)*wordLine+1);
for(i = 0;i < wordLine ; i++)
   list[i] = malloc(sizeof(char)*counter);  

変数に値を割り当てる必要がwordLineありますcounter

また、メモリ割り当ては次のループ(外部)の前に行う必要があります。

 while((c = fgetc(myFile)) != EOF){
  :
  :
 }

編集

質問の3番目のバージョンを新しくします。ファイルを2回読み取っています。したがって、2番目のループが開始する前に、fseek()、rewind()を最初のcharに 戻す必要があります。

試してみてください:

fseek(fp, 0, SEEK_SET); // same as rewind()
rewind(fp);             // same as fseek(fp, 0, SEEK_SET)

また、私はあなたの論理に疑問を持っていnumberOfLinesますmaxNumberOfChars。それも確認してください

編集

の計算が間違っていると思います。次のようにmaxNumberOfChars = 0, numberOfLines = 0してみてください。

maxNumberOfChars = 0, numberOfLines = 0, numberOfChars = 0;
while((c = fgetc(myFile)) !=EOF){
     if(c == '\n'){
         numberOfLines++; 
         if(maxNumberOfChars < numberOfChars)
             maxNumberOfChars = numberOfChars;
         numberOfChars=0
     }
     numberOfChars++;
}    

maxNumberOfChars1行の最大文字数です。

また、コードを変更します。

malloc(sizeof(char)*(maxNumberOfChars + 1));  
于 2013-02-09T08:48:18.217 に答える
1

私があなただったら、 を使用してファイルをプライベート メモリにマップし、ファイルをmmap反復処理して、 の配列に単語の先頭を格納し、を使用char**して増加できるようにしrealloc、改行を 0 に置き換えます。

そうすれば、単語を連続したブロックとしてメモリに保持できます。ファイル I/O を気にする必要はありません。これは、テキスト ファイル全体を としてメモリに保持しchar*、配列の配列を malloc する必要がないためです。 .

関数の詳細については、それぞれのマニュアルページを参照するか、コメントをドロップしてください:)

編集: mmap をまだ知らない場合は、これを見てください: http://www.jimscode.ca/index.php/component/content/article/13-c/45-c-simple-mmap-example

今日でもほとんどの C プログラマーは、ファイルをメモリに読み込もうとしますfopenが、これは完全に不必要であり、さらに複雑なレベルをもたらします。(バッファリング、配列の拡大など)そして、mmapすべての厄介な作業をOSに移す素晴らしい代替手段です

于 2013-02-09T09:16:30.510 に答える