@ikyos0612

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言語 連結リストのchar要素

解決したいこと

C言語で連結リストを使用して自動販売機システムを書いており、要素に文字列を含めているのですが、データを追加していくとすべてのセルの文字列要素が同じ文字列になってしまいます。どうしたら解決できるでしょうか。ポインタの指定の仕方がおかしいのでしょうか。

発生している問題・エラー

=====メニュー=====
 1.牛乳.....90円
 2.牛乳.....120円
 3.牛乳.....150円

該当するソースコード

main()関数内

	List* Drink = make_list();//ドリンクの在庫リストを作成
	strcpy_s(&temp_name, 20, "お茶");
	push(Drink,10,150,&temp_name);
	strcpy_s(&temp_name, 20, "コーヒー");
	push(Drink, 0, 120, &temp_name);
	strcpy_s(&temp_name, 20, "牛乳");
	push(Drink,10,90,&temp_name);

連結リストに用いる関数

// セル
typedef struct cell {
	int stock;//残数
	int value;//値段
	char *name;//名前
	struct cell* next;
} Cell;

// リスト
typedef struct {
	Cell* top;
} List;

// セルの生成
Cell* make_cell(int sto,int val,char *nam, Cell* cp)
{
    Cell* newcp = malloc(sizeof(Cell));
    if (newcp != NULL) {
        newcp->stock = sto;
        newcp->value = val;
        newcp->name = nam;
        newcp->next = cp;
    }
    return newcp;
}

// リストの生成
List* make_list(void)
{
    List* ls = malloc(sizeof(List));
    if (ls != NULL) {
        ls->top = make_cell(0, 0,NULL,NULL);  // ヘッダセルをセット
        if (ls->top == NULL) {
            free(ls);
            return NULL;
        }
    }
    return ls;
}

//n 番目の位置にデータを挿入する
bool insert_nth(List* ls, int n, int x,int y,char* z)
{   
    Cell* cp = nth_cell(ls->top, n - 1);
    if (cp == NULL) return false;
    cp->next = make_cell(x,y,z, cp->next);
    return true;
}

// 先頭に追加
bool push(List* ls, int x,int y,char* z)
{
    return insert_nth(ls, 0, x,y,z);
}
0 likes

1Answer

ひとつの文字列領域temp_nameを使いまわしているのでそうなります。
Cellを作るときに、name領域もmallocして文字列をコピーするといいですよ。固定サイズのchar配列にしてもいいかと思います。
それと、変数名は省略せずに書きましょう。参考: リーダブルコード

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

// セル
typedef struct cell {
	int stock;  //残数
	int price;  //値段
	char *name; //名前
	struct cell *next;
} *Cell;

// リスト
typedef struct {
	Cell top;
} *List;

// セルの生成
Cell make_cell(int stock, int price, const char *name)
{
    Cell cell = malloc(sizeof(Cell));
    if (cell == NULL) return NULL;
    cell->stock = stock;
    cell->price = price;
    cell->name = NULL;
    cell->next = NULL;
    if (name != NULL) {
        cell->name = malloc(strlen(name) + 1);
        if (cell->name == NULL) {
            free(cell);
            return NULL;
        }
        strcpy(cell->name, name);
    }
    return cell;
}

// リストの生成
List make_list(void)
{
    List list = malloc(sizeof(List));
    if (list == NULL) return NULL;
    list->top = make_cell(0, 0, NULL);  // ヘッダセルをセット
    if (list->top == NULL) {
        free(list);
        return NULL;
    }
    return list;
}

// 先頭に追加
bool push(List list, int stock, int price, const char *name)
{
    Cell cell = make_cell(stock, price, name);
    if (cell == NULL) return false;
    cell->next = list->top;
    list->top = cell;
    return true;
}

void dump_list(List list)
{
    printf("stock price name\n");
    for (Cell cell = list->top; cell->next; cell = cell->next) {
        printf("%5d %5d %s\n", cell->stock, cell->price, cell->name);
    }
}

int main()
{
    List drink = make_list();//ドリンクの在庫リストを作成
    push(drink, 10, 150, "お茶");
    push(drink,  0, 120, "コーヒー");
    push(drink, 10,  90, "牛乳");
    dump_list(drink);
}
実行結果
stock price name
   10    90 牛乳
    0   120 コーヒー
   10   150 お茶
1Like

Comments

  1. @ikyos0612

    Questioner

    丁寧に回答ありがとうございます!!理解出来ました。

Your answer might help someone💌