1

「学生」という名前の構造を作成するプログラムを書いています。特定の学生に関するさまざまなデータを入力する必要があります。これが今までの私のプログラムです。

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

struct student
{
  char* name;
  int id;
  float marks_1;
  float marks_2;

};

void main()
{
  int num, var_i, var_j, var_k, var_l, duplicated_id = 0;
  printf("Enter number of students\n");
  scanf("%d", &num);
  struct student s[num];
  printf("Enter the data for the students\n");
  for (var_i = 0; var_i < num; var_i++)
  {
    var_j = var_i + 1;
    printf("Enter name of student_%d\n", var_j);
    scanf(" %[^\n]%*c", &s[var_i].name);
    printf("Enter id of student_%d\n", var_j);
    scanf("%d", &s[var_i].id);
    for (var_k = 0; var_k < var_i; var_k++)
    {
      if (s[var_k].id == s[var_i].id)
      {
        printf("Duplicate Id, program will exit");
        return;
      }
    }
    printf("Enter marks(sub_1) of student_%d\n", var_j);
    scanf("%d", &s[var_i].marks_1);
    printf("Enter marks(sub_2) of student_%d\n", var_j);
    scanf("%d", &s[var_i].marks_2);

  }
}

次の for ループでは、以前に入力したすべての「id」値をチェックして、重複があるかどうかを確認しています。重複の場合、プログラムは終了します。

for(var_k=0;var_k<var_i;var_k++)
{ 
  if(s[var_k].id==s[var_i].id)
  {
    printf("Duplicate Id, program will exit");
    return;
  }
}

プログラムを終了する代わりに、ユーザーに別の値を入力するように求めます。これは、彼が一意の値を入力するまで続きます。どうすればいいですか?どんな助けでも感謝します。

4

2 に答える 2

3

これは間違っています:

scanf(" %[^\n]%*c", &s[var_i].name);

ポインターメンバーのアドレスを渡していますname(つまり、 を渡していますchar **) 。scanf()これには、フォーマット文字列に従って、char*その後読み取るデータを保持するのに十分なメモリが必要です。これは無効であり、未定義の動作s[]であり、配列内のデータをやみくもに上書きします。率直に言って、これがあなたのプロセスにセグメンテーション違反を起こさないことに驚いています。

これを変える:

struct student
{
  char* name;
  int id;
  float marks_1;
  float marks_2;
};

これに:

struct student
{
  char name[128]; // or some other suitable size.
  int id;
  float marks_1;
  float marks_2;
};

そしてこれを変更します:

scanf(" %[^\n]%*c", &s[var_i].name);

これに:

scanf(" %[^\n]%*c", s[var_i].name);

その呼び出しにもサイズリミッターを強くお勧めしscanf()ますが、それはあなたに任せます。API についてはこちらをご覧ください。

于 2013-08-23T17:23:52.763 に答える