質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.76%

  • C

    3461questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

入力した学籍番号とファイル読み込みした学籍番号が重複した場合に上書きするようにしたい。

解決済

回答 1

投稿

  • 評価
  • クリップ 1
  • VIEW 215

P_Beginner

score 2

上書きする方法を考えて見たのですが、以下の2通りを考えました。
1.ファイル読み込み繰り返し時に毎回重複していないか判断し、重複していたら読み込まない。
2.一度全てファイル読み込みし、重複を探し重複があったら削除。

このときのどちらかを組み込みたいです。

考えたプログラムコードは上の1番で、file_read関数部のwhile文を
check関数の一部を書き換えたif(strcmp(number,(std+i)->number) != 0)で囲ってみることにしたのですが(エラーになった)、検索をするわけではないのでnumberの部分が変わるのでしょうか?
それとも考え方が間違っているのでしょうか?

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

struct student{
    char number[10];    //学籍番号
    char name[50];        //氏名
};

void data_in(struct student *std);                            //入力
void data_out(struct student *std);                            //出力
void data_asc(struct student *std,int ninzu);                //昇順
void data_desc(struct student *std,int ninzu);                //降順
int data_delete(struct student *std,int ninzu,int search);    //削除
int file_read(struct student *std,int ninzu);                //読み込み
void file_write(struct student *std,int ninzu);                //書き込み
int check(struct student *std,int ninzu);                    //検索

int main(void)
{
    struct student std[22];    //生徒人数
    int ninzu=0,i,search;    //n:人数(データ数), i:繰り返し用, search:検索配列値格納用
    int menu,end=0;            //menu:処理選択用, end:終了用

    while(1)
    {
        printf("メニュー\n");
        printf("1:データ入力\n");
        printf("2:データ出力\n");
        printf("3:小さい順に整列\n");
        printf("4:大きい順に整列\n");
        printf("5:データ削除\n");
        printf("6:ファイルからデータ読み込み\n");
        printf("7:ファイルへのデータ書き込み\n");
        printf("8:データ検索\n");
        printf("9:終了\n");
        printf("実行する処理の番号-->");
        scanf("%d%*c", &menu);    //%*c:改行を読み飛ばす

        switch(menu)
        {
          case 1:            //入力
            if(ninzu>=22){    //既に22名のデータが存在する時
                printf("データ数が上限に達しています\n\n");
                break;
            }
            data_in(&std[ninzu]);
            ninzu++;                //人数を1人分増やす
            printf("\n");
            break;
          case 2:                    //表示
            for(i=0;i<ninzu;i++)    //入力した人数分
                data_out(&std[i]);
            if(ninzu==0)            //データが存在しない時
                printf("表示するデータがありません\n");
            printf("\n");
            break;
          case 3:            //昇順ソート
            if(ninzu==0){    //データが存在しない時
                printf("整列させるデータが存在しません\n\n");
                break;
            }
            data_asc(&std[0],ninzu);
            break;
          case 4:            //降順ソート
            if(ninzu==0){    //データが存在しない時
                printf("整列させるデータが存在しません\n\n");
                break;
            }
            data_desc(&std[0],ninzu);
            break;
          case 5:                            //削除
            search=check(&std[0],ninzu);    //検索した値の配列の中身を格納
            if(search>=0){                    //検索したデータと同じデータが見つかった場合
                data_out(&std[search]);
                ninzu=data_delete(&std[0],ninzu,search);
                printf("上記のデータを削除しました\n\n");
            }
            else{
                printf("データが存在しません\n\n");
            }
            break;
          case 6:                            //ファイル読み込み
            ninzu=file_read(&std[0],ninzu);    //読み込んだ時のデータ数を格納
            break;
          case 7:            //ファイル書き込み
            if(ninzu==0){    //データが存在しない時
                printf("書き込むデータが存在しません\n\n");
                break;
            }
            file_write(&std[0],ninzu);
            break;
          case 8:                            //検索
            search=check(&std[0],ninzu);    //検索した値の配列の中身を格納
            if(search>=0){                    //検索したデータと同じデータが見つかった場合
                printf("検索結果\n");
                data_out(&std[search]);
                printf("\n");
            }
            else{
                printf("データが存在しません\n\n");
            }
            break;
          case 9:    //終了
            end=1;    //終了条件の値を代入
            break;
          default:    //エラー
            printf("入力番号がありません\n\n");
        }
        if(end==1)    //終了条件の値が入っている時
            break;
    }
    return 0;
}
void data_in(struct student *std)    //入力
{
    printf("学籍番号---->");
    gets(std->number);                //学籍番号のデータ読み込み
    printf("名前---->");
    gets(std->name);                //氏名のデータ読み込み
}
void data_out(struct student *std)                //出力
{
    printf("%s\t%s\n", std->number, std->name);    //既存のデータ表示
}
void data_asc(struct student *std,int ninzu)                //昇順
{
    int i,j;
    struct student temp;

    //学籍番号を昇順にソート
    for(i=0;i<ninzu;i++){                                    //i番目のカウント
        for(j=i;j<ninzu;j++){                                //j番目のカウント
            if(strcmp((std+i)->number,(std+j)->number)>0){    //i番目の方が大きい時
                temp=*(std+i);                                //i番目のデータを退避
                *(std+i)=*(std+j);                            //j番目のデータを格納
                *(std+j)=temp;                                //i番目のデータを格納
            }
        }
    }

    printf("小さい順に並べかえました\n\n");
}
void data_desc(struct student *std,int ninzu)                //降順
{
    int i,j;
    struct student temp;

    //学籍番号を降順にソート
    for(i=0;i<ninzu;i++){                                    //i番目のカウント
        for(j=i;j<ninzu;j++){                                //j番目のカウント
            if(strcmp((std+i)->number, (std+j)->number)<0){    //i番目の方が小さい時
                temp=*(std+i);                                //i番目のデータを退避
                *(std+i)=*(std+j);                            //j番目のデータを格納
                *(std+j)=temp;                                //i番目のデータを格納
            }
        }
    }

    printf("大きい順に並べかえました\n\n");
}
int data_delete(struct student *std,int ninzu,int search)    //削除
{
    int i;

    for(i=search;i<ninzu;i++){    //検索した位置から人数を最後尾まで
        std[i]=std[i+1];        //削除してできた空き要素を詰める
    }
    ninzu--;                    //削除した分の人数を減ずる

    return ninzu;                //人数をmain関数に返す
}
int file_read(struct student *std,int ninzu)                                    //読み込み
{
    FILE *fin;
    char in_filename[20];
    int i=0;

    printf("入力ファイル名---->");
    gets(in_filename);                                                            //ファイル名の読み込み

    if((fin = fopen(in_filename,"r")) == NULL){                                    //ファイルが開けない時
        printf("ファイルが開けません\n\n");
        return ninzu;                                                            //人数をmain関数に返す
    }
    while(fscanf(fin,"%s\t%s",(std+ninzu)->number,(std+ninzu)->name) != EOF){    //ファイルのデータを読み込む
        ninzu++;                                                                //読み込んだ人数を増やす
        i++;                                                                    //ファイルのデータ数をカウント
    }
    
    if(i==0)
        printf("ファイルにデータが存在しません\n\n");
    else
        printf("ファイルを読み込みました\n\n");
    
    fclose(fin);                                                                //ファイルを閉じる
    
    return ninzu;
}
void file_write(struct student *std,int ninzu)                    //書き込み
{
    FILE *fout;
    char out_filename[20];
    int i;
    
    printf("出力ファイル名---->");
    gets(out_filename);                                            //ファイル名の読み込み
    
    if((fout = fopen(out_filename, "w")) == NULL){                //書き込み用ファイルを開けなかった時
        printf("ファイルが開けません\n");
        fclose(fout);                                            //ファイルを閉じる
    }
    
    for(i=0;i<ninzu;i++){                                        //人数分
        fprintf(fout,"%s\t%s\n",(std+i)->number,(std+i)->name);    //ファイルへ書き込む
    }
    
    printf("ファイルへ書き込みました\n\n");
    
    fclose(fout);                                                //ファイルを閉じる
}

int check(struct student *std,int ninzu)            //検索
{
    char number[10];
    int i;
    
    if(ninzu>0){                                    //データが存在する時
        printf("学籍番号を入力---->");
        gets(number);
        for(i=0;i<ninzu;i++){                        //人数分のデータを順番に
            if(strcmp(number,(std+i)->number) == 0) //一致する文字列(学籍番号)があった時
                return i;                            //データの位置をmain関数に返す
        }
    }
    
    return -1;                                        //見つけられなかったときに返す
}

    

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Zuishin

    2018/01/15 21:00

    前の質問をほったらかしにして次々と新しい質問をするものではありません。コメントには何らかの返信をし、解決したらベストアンサーを決め、解決しない場合はその旨伝え、自力で解決した場合には自己解決にしましょう。

    キャンセル

回答 1

checkベストアンサー

0

どのような運用をするか書いていないので憶測ですが、おそらく次のような手順で処理するものと思われます。
すでに何件かのデータがファイルに登録されている状態で、

  1. 読み込み
  2. 入力(重複なし)
  3. 入力(重複あり)

このとき3の処理をどうするか、かと思われます。
入力処理自体はあくまでも読み込み済みのデータに追加・上書きをすることになるので、ファイルを読み込んで云々はまったく不要。
なので入力処理を次のような流れにしてみてはいかがでしょうか。

  1. 学籍番号入力
  2. 登録済みかチェック(登録済みの場合、配列位置を取得)
  3. 登録済みの場合、上書きするか中止するかを問い合わせる
  4. 氏名入力
  5. 登録済みの場合、1の配列位置に氏名を登録
  6. 登録済みではない場合、空き要素に学籍番号・氏名を登録

3は勝手に考えた仕様なので、質問者様が決めてください(登録済みの場合は上書き禁止など)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3461questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • トップ
  • Cに関する質問
  • 入力した学籍番号とファイル読み込みした学籍番号が重複した場合に上書きするようにしたい。