0

学校のプロジェクトで c でクイズ プログラムを作成しています。質問と回答をテキスト ファイルに保存していました。テキスト ファイルには、1 つの質問と、それに続く 4 つの選択肢と正解 (それぞれが新しい行にある) などが含まれています。ファイル処理のコードは

#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<process.h>
void main()
{
int tnum=2,mnum;
printf("Enter a file name to load the quiz from or enter dhruv.txt to load the default file\n");
printf("(For type of file and arrangement of data in it, refer to the documentation\n");
printf("WARNING: An improper quiz file may result in malfunctioning of the program.\n");
char quizfile[100];
scanf("%s",quizfile);
FILE *dj;
dj = fopen(quizfile,"r");
int test = 1;
while(dj == NULL)
{
    printf("Requested file does not exist.Please enter a valid name\n");
    scanf("%s",quizfile);
    dj = fopen(quizfile,"r");
    test++;
    if(test == 5)
    {
    exit(0);
    }
}
char line[500];
char ques[20][500],ansa[20][500],ansb[20][500],ansc[20][500],ansd[20][500],anse[20][500];
int start = 1,quesval=1,ans1=1,ans2=1,ans3=1,ans4=1,ans5=1;
while(fgets(line,sizeof line,dj) != NULL)
{
    if((start%6) == 1)
    {
        strcpy(ques[quesval],line);
        quesval++;
    }
    if((start%6) == 2)
    {
        strcpy(ansa[ans1],line);
        ans1++;
    }
    if((start%6) == 3)
    {
        strcpy(ansb[ans2],line);
        ans2++;
    }
    if((start%6) == 4)
    {
        strcpy(ansc[ans3],line);
        ans3++;
    }

    if((start%6) == 0)
    {
        strcpy(anse[ans5],line);
        ans5++;
    }

    if((start%6) == 5)
    {
        strcpy(ansd[ans4],line);
        ans4++;
    }

    start++;

}
fclose(dj);
printf("Quiz file successfully loaded\n");
printf("/t/t WELCOME TO THE QUIZ\n\n");
printf("Every team must select one of the four correct answers to the asked questions to gain points\n");
printf("Wrong answer will not be penalized\n");
for(int k =1;k<quesval;k++)
{
    int myvar;
    myvar = k%tnum;
    if(myvar == 0)
    {
        myvar = tnum;
    }
    printf("Question for TEAM %d\n\n",myvar);
    printf("%s \n A.%s B.%s C.%s D.%s\n",ques[k],ansa[k],ansb[k],ansc[k],ansd[k]);
}
getch();
}

問題は

        if((start%6) == 0)
    {
        strcpy(anse[ans5],line);
        ans5++;
    }

プログラムは、これを使用するとファイルが存在しないことを示していますが、コメントアウトするとすぐにプログラムは正常に動作します。エラーの内容がわかりません。助けてください

編集:私のテキストファイルは次のようになります:

Who is the owner
dhruv
jain
kalio
polika
dhruv
who is his friend
sarika
katrina
jen
aarushi
aarushi
where is he
home
office
college
toilet
office
where will he go
home
office
college
toilet
home

編集 DOSBOXを使用してWindows 7でTurbo c ++を使用しています..スクリプトは上記で更新されています

4

2 に答える 2

1

入力ファイルを見ずに言うのは難しいですが、配列宣言が逆になっているのではないかと思います。たとえば、次のようになります。

 char ques[500][20];

これにより、500要素の配列が宣言されます。各要素は最大20文字です。あなたはおそらく欲しい:

 char ques[20][500];

これにより、20個の要素の配列が宣言され、各要素は最大500文字になります。

入力ファイルに20文字を超える行が含まれている場合は、現在のコードが配列を上書きしている可能性があります。

于 2012-10-15T18:02:47.657 に答える
0

ここにはいくつかの問題がありますが、当面の問題は次のとおりです。

strcpy(anse[ans5],line);

(そして、他のすべての strcpy 呼び出しも同様です。)

anse[1][0] から始まる配列に行をコピーしています。行に 20 文字を超える文字が含まれている場合、anse の末尾を超えてメモリが上書きされます。たとえば、行に 25 文字が含まれる場合、anse[1][0] から anse[1][24] に配置されます。anse は 20 文字しかないため、残念ながら anse[1][24] は存在しません。質問が 20 文字を超えると、メモリが破損し、クラッシュする可能性があります。推測してみましょう: 質問 5 は 19 文字を超えていますよね?

つまり、宣言で行と列が混同されています。それぞれ 500 文字の 20 の質問を許可したかったと思いますが、実際にはそれぞれ 20 文字の 500 の質問を許可しています。

次の問題: C では、配列は 1 から始まるのではなく、0 から始まります。たとえば、ques の最初の文字列は、ques[1] ではなく、ques[0] です。

これを簡単にするために、2 次元配列を行と列で構成されるテーブルと考えてください。たとえば、foo という名前の 3x4 配列を宣言します。

char foo[3][4];

次のようにイメージしてください。

   0 1 2 3
0  . . . .
1  . . . .
2  . . . .

私が持っているのは、それぞれ 4 文字の長さの 3 つの文字列の配列です。配列の最初の文字列は foo[0] にあります。最初の文字列の最初の文字は foo[0][0] にあります。2 番目の文字は foo[0][1] にあり、3 番目の文字列の 2 番目の文字は foo[2][1] のようになります。

これを解決するには、宣言を次のようにする必要があります。

char ques[20][500],ansa[20][500],ansb[20][500],ansc[20][500],ansd[20][500],anse[20][500];
int start = 1,quesval=0,ans1=0,ans2=0,ans3=0,ans4=0,ans5=0;

機能するようになったら、一度だけ変更されるのに、ループを通過するたびに start の値を 6 回テストする理由を自問する必要があります。ここで利用可能なはるかに優れたソリューションがあります。次のような 3 次元配列を考えてみましょう。

char answers[20][500][5];

これにより、それぞれ 5 つの回答を持つ 20 の質問が得られます。

于 2012-10-15T18:43:06.437 に答える