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

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

ただいまの
回答率

87.78%

ユーザーが入力した値をcsvファイルに書き込む

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 259

score 1

すべてのコードを載せましたがメイン関数を主に見ていただきたいです。
ユーザーが入力した情報をリスト構造で作ったプログラムです。
このユーザーが入力した情報をcsvファイルに書き込みたいのですが、なかなかうまくいきません。
何かアドバイスいただけたら幸いです。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NAME_LEM_MAX 10
#define ADDRESS_LEM_MAX 64
#define BIRTH_LEM_MAX 10
#define NUMBER_LEM_MAX 16
#define NO_PROBLEM 0
#define ERROR 1

typedef struct student
{
    char id;
    char name[NAME_LEM_MAX + 1]; 
    char address[ADDRESS_LEM_MAX + 1]; 
    char birth[BIRTH_LEM_MAX + 1];  
    char phone_number[NUMBER_LEM_MAX + 1]; 
    struct student *next;  // 次のデータがある場所
} PERSON_t;

static PERSON_t *head = NULL; // リストの先頭 ノードが存在するアドレス
static PERSON_t *tail = NULL; // リストの末尾

int add_person(int id);
int delete_person(void);
int change_person(void);
void  person_result(void);
void get_string(char *str, unsigned int num);
int get_person_id(PERSON_t *p);
int get_person_name(PERSON_t *p);
int get_person_address(PERSON_t *p);
int get_person_birth(PERSON_t *p);
int get_person_phone_number(PERSON_t *p);

int main(void)
{
    int number = 0;
    int id = 0;
    int ret;
    int end_flag = 0;
    int i = 0;
    PERSON_t *current, *data;
    FILE *fp;

    fp = fopen("test.csv","w");
    if( fp == NULL ){
        perror("error");
        return -1;
    }else{
        puts("ok");
    }

    fprintf(fp, "名前,住所,誕生日,電話番号\n");
    fclose(fp);

    while(end_flag == 0)
    {
        printf("---------------------------------------------\n");
        printf("1.一覧\n2.一件表示\n3.追加入力\n4.変更\n5.削除\n0.終了\n ");
        scanf("%d",&number);
        fflush(stdin);
        switch(number){
               case 1:
                person_result();
                break;
            case 2:
                person_result();
                break;
            case 3:
                id++;
                ret = add_person(id); 
                if(ret == NO_PROBLEM){
                    puts("追加完了");
                }
                break;
            case 4:
                ret = change_person();
                if(ret == NO_PROBLEM){
                    puts("変更完了");
                }
                break;
               case 5:
                ret = delete_person();
                if(ret == NO_PROBLEM){
                    puts("削除完了");
                }
                break;
            case 0:
                puts("終");
                end_flag = 1;
                break;
            default:
                //何もしない
                break;
        }

    }

    fscanf(fp,"%d",data->id);
    printf("%d",data->id);

    fprintf(fp,"%d",data->id);

    fclose(fp);
    return 0;
}


int change_person(void)
{
    int ret = NO_PROBLEM;
    int number;
    PERSON_t *current, *data;
    int changeId = 0;
    int end_flag = 0;
    puts("何番目のIDを変更しますか");
    scanf("%d", &changeId);
    fflush(stdin);
    current = head;  // リストの先頭から、挿入先ノードを探す
   while (current != NULL)
    {
        if(current->id == changeId)
        {  
            break;  // ノードが見つかればループ終了
        }
        else
        {
            current = current->next;
        }
    }

    if (current == NULL)   // 検索結果なし
    {
        puts("そのようなデータはありません");
        ret = ERROR;
        return ret;
    }

    printf("ID→%d\n",current->id);
    while(end_flag == 0){
        printf("--------------------------\n");
        printf("(1:名前, 2:住所, 3:誕生日, 4:電話番号, 5:終了) = ");
        scanf("%d",&number);
        fflush(stdin);

        switch(number){
            case 1:
                get_person_name(current);
                break;
            case 2:
                get_person_address(current);
                break;
            case 3:
                 get_person_birth(current);
                break;
            case 4:
                get_person_phone_number(current);
                break;
            case 5:
                end_flag = 1;
                break;
            default:
                // 何もしない
                break;
        }
    }
    return ret;
}

int add_person( int id)
{
    PERSON_t *data;
    int ret = NO_PROBLEM;

    data = (PERSON_t *)malloc(sizeof(PERSON_t));  //領域確保

    data->id = id;   //data->idに代入
    printf("ID→");
    printf("%d\n",data->id);  
    get_person_name(data);
    get_person_address(data);
    get_person_birth(data);
    get_person_phone_number(data);

    if (head == NULL) //一回目は必ずここを通る
    {
        head = data;  // リストが空の場合 新しいノードが、先頭かつ末尾になる 
        tail = data; //先頭と末尾にdataをセット
    }
    else   // リストに1件以上ノードが存在する場合 2回目からはここを通る
    {
        tail->next = data; // 末尾ノードのnextに、新しいノードの場所をセット
        tail = data;         // 追加した新しいノードをtailとする
    }
    tail ->next = NULL;     // 次のデータは無いので、nextにはNULLをセット
    return ret;
}


/*
 * 機能:指定したリストを開放
 * 戻り値:なし
 */
int delete_person(void)
{

    int deleteId;
    int ret = NO_PROBLEM;
    PERSON_t *current; //現在の場所
    PERSON_t *prev;  //前の場所    
    printf("削除するIDを入力してください。\n");
    scanf("%d",&deleteId);
    fflush(stdin);
    current = head; // リストの先頭から、idが一致するノードを探す
    prev = NULL;


    while (current != NULL)
    {
        if(current->id == deleteId)
        {  
            break;  // ノードが見つかればループ終了
        }
        else
        {
            prev = current;   // 現在のノードを1つ前のノード(prev)として記憶
            current = current->next;
        }
    }
    if (current == NULL)   // 検索結果なし
    {
        puts("そのようなデータはありません");
        ret = ERROR;
    }
    else if (current == head)  // 削除対象が先頭のノードだった場合
    {
        head = current->next;   // 先頭の次のノードを新しいheadとする
        free(current);   // 削除対象のノードを開放
    }
    else  // 削除対象が先頭のノードではない場合
    {
        prev->next = current->next;    // 「削除対象の1つ前」のnextに「削除対象のnext」をセット
        free(current);                 // 削除対象のノードを開放
    }
    return ret;
}

/*
 * 機能:リストの内容を全て表示する
 * 戻り値:なし
 */

void  person_result()
{
    int number;
    PERSON_t *current;
    if ((head == NULL) && (tail == NULL)) {
        puts("リストは空です"); // 表示するものがない
        return;
    }
    printf("(0:一覧表示, 1以上:指定されたインデックスを表示) = ");
    scanf("%d",&number);

    current = head;   // 先頭から表示するので、現在の位置をheadにする
    if( number == 0 ){
        printf("----------------------------------\n");
        while (1)
        {   
            printf(" ID:%d\n 名前:%s\n 住所:%s\n 生年月日:%s\n 電話番号:%s\n",current->id, current->name, current->address, current->birth, current->phone_number);
            printf("----------------------------------\n");
            if (current->next != NULL)
            {
                current = current->next;   // 現在の場所を次のノードに移動
            }
            else  //次のデータはないので、break
            {
                break;
            }
        }
    }

    else if( number >= 1 ){
        int displayId = 0;
        printf("表示するIDを入力してください。\n");
        scanf("%d", &displayId);
        printf("id:%d\n",current->id);
        printf("dis:%d\n",displayId);

        while (current != NULL){
            if( current->id == displayId)

            { 
                printf(" ID:%d\n 名前:%s\n 住所:%s\n 生年月日:%s\n 電話番号:%s\n",current->id, current->name, current->address, current->birth, current->phone_number);
                break;
            } else {
                current = current->next;
            }
        }
        if( current == NULL ){
            puts("そのようなデータはありません");
        }
    }
}

/*
 * 機能:ユーザーが入力した文字を取得する
 * 引数1 str:構造体メンバのポインタ
 * 引数2 num:構造体メンバの確保したメモリの長さ
 * 戻り値:なし
 * */

void get_string(char *str, unsigned int num)
{  
    int  i = 0;
    int  c = 0;
    memset(str, 0,  num );
    while (strlen(str) < num - 1 ) { 
        c = getchar();
        if (c != '\n') { 
            str[i] = c;
            i++;
        } else { 
            break; 
        } 
    }
    while(c != '\n'){
        c = getchar();
    }
}

/*
 * 機能:ユーザー名を取得する
 * 引数1 p: ユーザー情報構造体のポインタ
 * 戻り値:0
 * */

int get_person_name(PERSON_t *p){  
    int ret = NO_PROBLEM;    
    while(1){
        printf("名前→");
        get_string(  p->name, sizeof p->name );  //dataポインタを格納した配列arrayからメンバにアクセス
        if( 0 < strlen(p->name) ){
            break;
        }else{
            printf("未入力です。\n再入力してください。\n\n");
        }
    }
    return ret;
}

/*
 * 機能:ユーザー住所を取得する
 * 引数1 p: ユーザー情報構造体のポインタ
 * 戻り値:0
 */
int get_person_address(PERSON_t *p){
    printf("住所→");    
    get_string(  p->address, sizeof p->address );
    return 0;
}

/*
 * 機能:ユーザー生年月日を取得する
 * 引数1 p: ユーザー情報構造体のポインタ
 * 戻り値:エラーコード
 */
int get_person_birth(PERSON_t *p){
    unsigned int i;
    int ret = NO_PROBLEM;
    while(1){
        printf("生年月日→");    
        get_string(  p->birth, sizeof p->birth );    //アドレスと長さを渡している
        if( 0 < strlen(p->birth)){
            for(i = 0; i < strlen(p->birth); i++){                          
                if (!(('0' <= p->birth[i]  && p->birth[i] <= '9') || p->birth[i] == '/' )){  
                    strcpy(p->birth,"エラー");
                    ret = ERROR;
                    break;
                }
            }
            break;
        }else{
            printf("未入力です。\n再入力してください。\n\n");
        }
    }
    return ret;
}

/*
 * 機能:ユーザー電話番号を取得する
 * 引数1 p: ユーザー情報構造体のポインタ
 * 戻り値:エラーコード
 */
int get_person_phone_number(PERSON_t *p){
    unsigned int i;
    int ret = NO_PROBLEM;
    while(1){
        printf("電話番号→");    
        get_string(  p->phone_number, sizeof p->phone_number );
        if( 0 < strlen(p->phone_number)){
            for(i = 0; i < strlen(p->phone_number) ; i++){    
                if(!(('0' <= p->phone_number[i]  && p->phone_number[i] <= '9') || p->phone_number[i] == '-')){
                     ret = ERROR;
                    strcpy(p->phone_number,"エラー");
                    break;
                }
            }
            break;
        }else{
            printf("未入力です。\n再入力してください。\n\n");
        }
    }
    return ret;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • y_waiwai

    2021/05/12 21:06

    このコードではどういうふうになるんでしょうか

    キャンセル

  • CulbFight

    2021/05/12 21:15

    説明不足でした。test.csvが開かれて、fprintf(fp, "名前,住所,誕生日,電話番号\n")でcsvファイルにそれぞれ書き込まれます。

    その後ユーザーに情報の入力を促し、入力したものが、確保したメモリに格納されます。

    このユーザーが入力した値をcsvファイルに書き込みたいという質問になります。

    キャンセル

  • episteme

    2021/05/13 07:51

    コンパイル・エラーとなります。

    キャンセル

回答 2

+1

ひんと

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NAME_LEM_MAX 10
#define ADDRESS_LEM_MAX 64
#define BIRTH_LEM_MAX 10
#define NUMBER_LEM_MAX 16

typedef struct student {
    char id;
    char name[NAME_LEM_MAX + 1];
    char address[ADDRESS_LEM_MAX + 1];
    char birth[BIRTH_LEM_MAX + 1];
    char phone_number[NUMBER_LEM_MAX + 1];
    struct student* next;  // 次のデータがある場所
} PERSON_t;

int main() {
  // おためしに3つのPERSON_tでリストをつくる
  PERSON_t first  = { 'A', "name-a", "addr.-a", "birth-a", "phone-a", NULL };
  PERSON_t second = { 'B', "name-b", "addr.-b", "birth-b", "phone-b", NULL };
  PERSON_t last   = { 'C', "name-c", "addr.-c", "birth-c", "phone-c", NULL };
  first.next = &second;
  second.next = &last;
  last.next = NULL;

  // CSVを書く
  FILE* fp = fopen("test.csv", "w");
  for ( PERSON_t* curr = &first; curr != NULL; curr = curr->next ) {
    fprintf(fp, "%c, %s, %s, %s, %s\n", curr->id, curr->name, curr->address, curr->birth, curr->phone_number);
  }
  fclose(fp);

  return 0;
}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

check解決した方法

-1

ヒントをもとに実装することができました。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2021/05/13 18:17 編集

    こう言う場合は直接役に立ったヒントを提供していただいた回答にベストアンサーを差し上げ、自分の回答では「ではそのヒントを用いてどうコードを書き、解決したのか」の具体的コードを書くなりして質問を閉じます。そうでないと全て自己解決(さも、自分だけで解決したように)で終わっちゃいますよね。そもそも回答者に対して失礼です。

    [質問を解決済みにしたい] https://teratail.com/help#resolve-question

    キャンセル

  • 2021/05/13 19:13

    もうこの質問は解決済みのため、修正できないのですね。。。
    以後気を付けます。

    キャンセル

  • 2021/05/13 21:12

    ベストアンサーは変更することが可能です。

    キャンセル

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

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

関連した質問

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