0
#include <stdio.h>
#include <math.h>
#include <string.h>
int main(void)
{
    int menuswitch=1;
    int amountofstudents;
    int fname[50];
    int lname[50];
    int grade[50];
    int i;
    char studentinfo[100];
    printf("Enter Amount of Students: ");
    scanf("%d", &amountofstudents);
    for (i=0;i<amountofstudents;i++)
    {
        gets(studentinfo);
        strcpy(fname[i], strtok(studentinfo, " "));
        strcpy(lname[i], strtok(NULL, " "));
        strcpy(grade[i], strtok(NULL, " "));
    }

よし、strtok を少し使用する必要があります。後でソートするために入力文字列の一部を保存しようとしています。strtok を使用して文字列を分割し、各ピースを対応する配列に配置することを考えていました。それでも、試行するたびに、Visual Studios で Access Violation というエラーが表示されます。事前に助けてくれてありがとう

エラーは

First-chance exception at 0x5120F7B3 (msvcr110d.dll) in Lab 2.exe: 0xC0000005: Access violation reading location 0x00000000.
Unhandled exception at 0x5120F7B3 (msvcr110d.dll) in Lab 2.exe: 0xC0000005: Access violation reading location 0x00000000.

入力は

FirstName Lastname 80(Grade)
4

3 に答える 3

1

大きな問題の 1 つは、文字列ではなく整数値にコピーしようとすることです。整数配列を文字列の配列に変更します。

...
char fname[50][100];
char lname[50][100];
char grade[50][100];
...

関数にも問題がありgetsます(廃止されており、使用しないでください)。つまり、前の関数scanfは入力バッファから改行を削除しないため、最初のgets呼び出しでこの空の改行が表示され、空の行が表示されます(これはチェックしません)。

scanfこれは、フォーマット文字列の の後にスペースを追加して、末尾の空白を破棄するように指示することで簡単に解決され"%d"ます。

scanf("%d ", &amountofstudents);
/*       ^    */
/*       |    */
/* Note space */

の代わりにgets、次のものを使用する必要がありますfgets

fgets(studentinfo, sizeof(studentinfo), stdin);

最後に、常にエラーをチェックしてください。

于 2013-10-15T05:21:45.660 に答える
0

あなたが抱えている問題は、3 つの変数 (fname、lname、および grade) を char[] (配列) として宣言したことです (まあ、それはあなたが使用するつもりだった型です)。生徒の情報です。そして、後で strtok() から char[] にしたいものにコピーしようとしましたが、fname[i] (lname[i], grade[i]) を逆参照したため、それらは char ではなく char 型です。 []。

終了するには stdlib.h が必要です。

#include <stdio.h>
#include <stdlib.h> //for exit
#include <string.h>
//#include <math.h> //you don't need this, yet
#define STUDLIMIT (100)

fname[]、lname[]、grade[] の配列を作成できます (ここを参照してください: http://www.cs.swarthmore.edu/~newhall/unixhelp/C_arrays.html )、

int main(void)
{
    //int menuswitch=1; //you aren't using this
    int amountofstudents;
    char studentinfo[100];
    char fname[STUDLIMIT][50];
    char lname[STUDLIMIT][50];
    char grade[STUDLIMIT][50];
    int ndx;
    printf("Enter Amount of Students: ");
    if( (fscanf(stdin,"%d ", &amountofstudents)<=0)
    || (amountofstudents<1) || (amountofstudents>STUDLIMIT) )
    {
        printf("need %d to %d studends\n",1,STUDLIMIT); exit(0);
    }
    for (ndx=0;ndx<amountofstudents;ndx++)
    {
        printf("Student: "); fflush(stdout);
        fgets(studentinfo,sizeof(studentinfo),stdin);
        strcpy(fname[ndx], strtok(studentinfo, " "));
        strcpy(lname[ndx], strtok(NULL, " "));
        strcpy(grade[ndx], strtok(NULL, " "));
    }
}

または、入力された学生情報を保持する struct(ure) を作成し、これらの学生レコードの配列を、入力して保存する学生ごとに 1 つずつインスタンス化することができます。

typedef struct student
{
    char fname[50];
    char lname[50];
    char grade[50];
} StudentObj;
int StudentCopy(StudentObj*sp,char*fname,char*lname,char*grade)
{
    if(!sp || !fname || !lname || !grade ) return -1;
    strcpy(sp->fname, fname);
    strcpy(sp->fname, lname);
    strcpy(sp->fname, grade);
}
StudentObj students[STUDLIMIT];
int main(void)
{
    //int menuswitch=1; //you aren't using this
    int amountofstudents;
    char studentinfo[100];
    char fname[50];
    char lname[50];
    char grade[50];
    int ndx;
    printf("Enter Amount of Students: ");
    if( (fscanf(stdin,"%d ",&amountofstudents)<=0)
    || (amountofstudents<1) || (amountofstudents>STUDLIMIT) )
    {
        printf("need %d to %d studends\n",1,STUDLIMIT); exit(0);
    }
    for (ndx=0;ndx<amountofstudents;ndx++)
    {
        printf("Student: "); fflush(stdout);
        fgets(studentinfo,sizeof(studentinfo),stdin);
        strcpy(fname, strtok(studentinfo, " "));
        strcpy(lname, strtok(NULL, " "));
        strcpy(grade, strtok(NULL, " \n\r"));
        StudentCopy(&(students[ndx]),fname,lname,grade);
    }
}
于 2013-10-15T05:47:56.890 に答える
0

潜在的な問題はscanf/gets combo. 代わりfgets()に使用し、必要に応じて整数に変換しますatoi()strtok から返されたものについてサニティチェックを行うのも良い方法です(入力について何も仮定することは決して良いことではありません)

char* token = strtok(studentinfo, " ");
if ( strlen(token) < sizeof(fname[i]) )
{
  strcpy(fname[i], token);
...

また、文字列を整数配列として宣言しました。それらは char にする必要があります。char fname[50];

于 2013-10-15T05:07:46.453 に答える