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

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

ただいまの
回答率

90.50%

  • C

    4539questions

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

構造体、ポインタ、スタック

解決済

回答 2

投稿 編集

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

rig

score 1

入力例~

人数:3
学籍番号:123
名前:佐藤
学籍番号:456
名前:田中
学籍番号:789
名前:前田

出力例~

学籍番号:789
名前:前田
学籍番号:456
名前:田中
学籍番号:123
名前:佐藤

というような新しく入力されたデータ順に出力するプログラムを作りたいのですが、下のプログラムを実行すると

学籍番号:789
名前:前田
学籍番号:789
名前:前田
学籍番号:789
名前:前田

と出力されてしまいます。最初に述べたように出力できるようどこが間違えていてどうしたら希望通り出力できるのか教えてください。

ソースコード~

include<stdio.h>

include<stdlib.h>

define STACKSIZE 100

typedef struct personaldata {

char *stnum, *name;

}PD;

PD data[STACKSIZE];
int sp = -1;

int push(char *a, char *b)
{
if (sp >= STACKSIZE - 1)
return -1;

sp++;

data[sp].stnum = a;
data[sp].name = b;

return 0;
}

int pop(char *a, char *b) {
if (sp < 0)
return -1;

printf("\n%d\n", sp);
a = data[sp].stnum;
b = data[sp].name;
sp--;

printf("学籍番号:%s\n名前:%s\n", a, b);
return 0;
}

int main(void) {

int i, n;
char a[STACKSIZE], b[STACKSIZE];
PD *data;

printf("人数:");
scanf("%d", &n);

data = (PD *)calloc(n, sizeof(PD *));

for (i = 0; i < n; i++)
{
printf("学籍番号:");
scanf("%s", a);

printf("名前:");
scanf("%s", b);

push(a, b);

}

for (i = 0; i < n; i++)
pop(a, b);

return 0;
}

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • episteme

    2018/12/05 20:44

    「というようなプログラム」ってなによ。学籍番号の大きい順かい? 説明せよ。

    キャンセル

  • rig

    2018/12/05 20:53

    情報不足すみません。スタックを用いたいので入力されたのが新しい順です。

    キャンセル

回答 2

checkベストアンサー

+2

int push(char *a, char *b)
{
    if (sp >= STACKSIZE - 1)
        return -1;
    sp++;
    data[sp].stnum = a;
    data[sp].name = b;

    return 0;
}

ここでdata[sp].stnumaのアドレス、data[sp].namebのアドレスをコピーしてるためです。
(文字列のコピーをしてないためです)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/12/05 21:16

    回答ありがとうございます。では、この場合どう改善すればよいのですか
    聞いてばかりですみません

    キャンセル

  • 2018/12/05 22:04

    文字列のコピーなのでstrncpyを使います
    http://www.orchid.co.jp/computer/cschool/CREF/strncpy.html

    ただしメモリ確保が必要なので注意

    キャンセル

+2

for (i = 0; i < n; i++)
{
printf("学籍番号:");
scanf("%s", a);
printf("名前:");
scanf("%s", b);
push(a, b);

このa,b のアドレスはずっと同一と言うのは理解できるでしょうか。
このループ内でずっと同じ場所の配列に上書きするだけで、pushしているアドレスは全て同一となります

あとでプリントしてもすべて同じになるのはこのせいです

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/12/05 21:35

    回答ありがとうございます。すみませんが、どう変えれば希望通りの実行結果になるかを具体的に教えていただけると助かります。わがままをすみません

    キャンセル

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

  • C

    4539questions

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