4

Cに関する私の質問に関連するいくつかの投稿を読みました.これは確かに私のエラーを減らすのに役立ちます. ただし、他の投稿では解決できなかった問題がまだ残っています。基本的に、これは私がやろうとしていることです。

main で配列を定義します。この配列へのポインターを関数に渡します。この関数は、ファイルを開き、そのファイルを解析し、そのファイルからの情報を、渡したポインターの配列に入れます。まあ、失敗します。

私が得るエラーは次のとおりです。

work.c:12: error: array type has incomplete element type
work.c: In function ‘main’:
work.c:20: error: type of formal parameter 1 is incomplete
work.c: At top level:
work.c:25: error: array type has incomplete element type

コード全体は以下のとおりです。ただし、配列やポインターなどをどのように定義したかに注目するだけでよいと思います。

#include <stdio.h>
#include <stdlib.h>

//Defining Preprocessed Functions 
char readFile(char array[][], int, int);
//void displayStudentInfo(int*);

//Implements Step 1 and 2 of Student Instuctions
int main(int argc, char* argv[])
{
    int x = 256;
    int y = 256;
    char arrays[x][y]; 
    readFile(&arrays,x,y);
    //displayStudentInfo(&array);
    return 0;
}

char readFile(char array[][], int x, int y)
{
    char line[256]; //Three columns 0, 1, 2 corresponds to firstname, lastname, score. 
    char* string;
    int columns = 3;

    x = 0;
    //int y; //Defines rows and columns of 2D array to store data
    //char array[x][y]; //Defines the array which stores firstname, lastname, and score



    FILE *file;
    file = fopen("input.txt", "r");

    //Test to make sure file can open 

    if(file  == NULL)
    {
        printf("Error: Cannot open file.\n");
        exit(1);
    }
    else
    {
        while(!feof(file))
        {
          /* 
            if(fgets(line, 256, file))//fgets read up to num-1 characters from stream and stores them in line
            {
                printf("%s", line);
            }
            */
            if(fgets(line,256,file)!=NULL)
            {
                for(y = 0; y < columns; y++)
                {
                    array[x][y]=strtok(fgets(line,256,file), " ");
                }
                x++;
            } 
        }
    }
    fclose(file);
}
4

3 に答える 3

3

いくつか問題があります。最初の 2 つは似ています。

まず、関数宣言で無制限の配列を使用しています。コンパイラは、引数、つまり次元について詳しく知る必要があります。この場合、ディメンションの 1 つを指定するだけで十分です。

char readFile(char array[][NUM_Y], int, int);

これで、コンパイラは配列を処理するのに十分な情報を取得しました。このようにディメンションを省略できますが、通常は明示的に記述し、関数を次のように宣言することをお勧めします。

char readFile(char array[NUM_X][NUM_Y], int, int);

次に、メインで配列を宣言するときはarrays、関数の引数リストと同様に、次元についてより具体的にする必要があります。

char arrays[x][NUM_Y];

NUM_Y予想されるデータ量に十分な大きさを選択してください。

次に、初期化を行わずxymainこれらの変数を使用して配列を宣言します。これらの変数には を含むガベージ値が含まれる可能性があり0、予期しない次元/サイズの配列になってしまうため、これは悪いことです。

最後に、配列を関数に渡すときは、逆参照せずに変数を渡すだけです。

readFile(arrays, x, y);

C では、配列を関数に渡すと、実際に渡されるのは最初の要素へのポインターです。これは、配列がコピーされないことを意味するため、関数は、変更が予想されるメモリ領域にアクセスできます。逆参照を行っているのは、関数内で変更したいintsorstructsのような単純な型を渡す方法を学んだためだと思いますが、配列ではこれを行う必要はありません。

于 2012-07-29T21:51:30.583 に答える
2

char arrays[x][y];: x,y は変数ではなく、定数または実際の値でなければなりません: http://www.acm.uiuc.edu/webmonkeys/book/c_guide/1.2.html#arrays

この制限を回避するには、代わりにポインターを宣言し、malloc(sizeof(byte)*x) によって予約された各位置で、malloc(sizeof(byte)*y) x 回を使用して必要なメモリを予約するときに返されるアドレスに割り当てます。http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.13.html#malloc

于 2012-07-29T21:39:18.407 に答える
1

定義では

char arrays[x][y];

y常に const にする必要があります。これには絶対に例外はありません。その他の次元 -x一部のコンパイラのみでスタック上にオブジェクトを定義する場合、変数にすることができます。

于 2012-07-29T21:52:29.213 に答える