nakata_nakata
@nakata_nakata (N)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

C言語の課題

C言語の課題です

会社でC言語の勉強を始めた二週間でこの問題を出され難航しています。
助けて頂けると幸いです。

問題

実行プログラムと同じところにある任意のテキストファイルを読み込んで下記の内容を行う
読み込むテキストファイルは名簿となっている。
一行がレコードになっている、最大レコード数は10レコード。多い場合は捨てる。
各要素は,(カンマ)で区切られている。

1個の要素は氏名IDでサイズは10バイトである。(ユニーク属性)
他に同じIDが存在すればエラーを出す。
2個目の要素は氏名でサイズは20バイト。
多い場合はエラー
3個目の要素は所属組織で20バイトある。
多い場合はエラー
4個目の要素は役職で20バイトである。
多い場合はエラー

なお要素が4個に満たない場合、多い場合はエラーとする。
読み取った内容は一旦構造体に格納する事。
名簿を読み取ったら標準出力に下記の容量で表示させる。

例)

ID=0000000000
氏名=あああああ
組織=いいいいい
役職=ううううう

ID=0000000001
氏名=かかかかか
組織=ききききき
役職=くくくくく

レコードイメージ

0000000000,あああああ,いいいいい,えええええ
0000000001,かかかかか,ききききき,くくくくく
0000000000,あああああ,いいいいい,えええええ ←エラー
0000000003,さささささささささささ,ししししし,すすすすす ←エラー

読み取ることはできましたがうまく構造体に入れる事ができませんでした。
答えを教えてもらうとまたコードもまた投稿します。
よろしくお願いします。

0

2Answer

Comments

  1. @nakata_nakata

    Questioner

    一旦出来た所まであげます。
    少々お待ち下さい。

あまりきちんと検証していませんが実装してみました。
データのサンプル的に固定長ではないはずだと思って、そのように実装しています。
ちなみに記載のサンプルですとIDが全部全角文字になってるのでSJISで20バイト、UTF-8だと30バイトで全部エラーになりそうなのですが

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

#define MAX_RECORD_LENGTH 10
#define LINE_BUFFER 256
#define TRUE 1
#define FALSE 0

typedef struct {
    char id[10];
    char name[20];
    char organization[20];
    char position[20];
} record_t;

int parse_record(const char *line, record_t *record) {
    char str[strlen(line)], *tp;
    record_t _record;
    strcpy(str, line);
    tp = strtok(str, ",");
    if(!tp || strlen(tp)>10) return FALSE;
    strcpy(_record.id, tp);
    tp = strtok(NULL, ",");
    if(!tp || strlen(tp)>20) return FALSE;
    strcpy(_record.name, tp);
    tp = strtok(NULL, ",");
    if(!tp || strlen(tp)>20) return FALSE;
    strcpy(_record.organization, tp);
    tp = strtok(NULL, ",\n");
    if(!tp || strlen(tp)>20) return FALSE;
    strcpy(_record.position, tp);
    if(strtok(NULL, ",")) return FALSE; // 役職列以降にデータが有ればエラー
    memcpy(record, &_record, sizeof(record_t));
    return TRUE;
}

int check_unique(const record_t new_record, const record_t *record_array, const size_t len) {
    for(int i=0; i<len; i++) {
        if(strcmp(new_record.id, record_array[i].id) == 0) return FALSE;
    }
    return TRUE;
}

int main() {
    FILE *fp;
    record_t record_array[MAX_RECORD_LENGTH];
    size_t count = 0;
    char line[LINE_BUFFER];

    printf("ファイルオープン\n");
    fp = fopen("./record.txt", "r");
    if(fp == NULL) {
        printf("Error : file\n");
        return -1;
    }

    printf("--- ファイル読み込み開始 ---\n");
    while(fgets(line, LINE_BUFFER, fp) != NULL) {
        if(count > MAX_RECORD_LENGTH) {
            printf("Error : count\n");
            continue;
        }

        record_t record;
        if(!parse_record(line, &record)) {
            printf("Error : parse\n");
            continue;
        }
        if(!check_unique(record, record_array, count)) {
            printf("Error : unique\n");
            continue;
        }

        memcpy(&(record_array[count]), &record, sizeof(record_t));
        ++count;
    }

    printf("--- ファイル読み込み終了 ---\n");
    printf("Total count : %zu\n", count);
    for(int i=0; i<count; i++) {
        printf("count:%d, id:%s, name:%s, organization:%s, position:%s\n",
               i, record_array[i].id, record_array[i].name, record_array[i].organization, record_array[i].position);
    }
}

0Like

Comments

  1. @nakata_nakata

    Questioner

    ありがとうございます。
    IDは半角です。サンプルミス失礼しました。
    これで意味をしっかり捉え学習します。

Your answer might help someone💌