掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.24875

異常終了する原因は構造体変数か
投稿者---あきき(2005/12/19 22:34:03)


当サイトの15-2の例題をお借りして構造体変数について学習していますが、1件入力してENTERキーを押すなり異常終了します。現在、原因究明中です。どなたか、助言の程お願いします。

/*---------------------------------------------------------------------------------
    貸し出し書籍設定処理
---------------------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>

struct ymd {
        int  yy;
        int  mm;
        int  dd;
};
struct library {
        char *name;
        struct ymd date;
};
typedef struct library lib_t;

int main( void )
{
    lib_t work = {"",0,0,0};
    lib_t lib[100];
    int i,cnt=0;

    printf("          図書名、返却予定年月日を入力しなさい。(終了条件:Ctrl+Z)\n");
    while (scanf("%s %d %d %d",work.name, &work.date.yy, &work.date.mm, &work.date.dd)!=EOF){
        //貸し出し中か?
        for( i=0; i<cnt; i++){
            if(strcmp( work.name, lib[i].name) == 0) {
                printf("貸し出し中です。別の本を指定してください。\n");
                break;
            }
        }
        if( i == cnt){
            printf("貸し出し出来ます。\n");
            lib[i] = work;
            cnt++;
        }
        printf("          図書名、返却予定年月日を入力しなさい。(終了条件:Ctrl+Z)\n");
    }
    // 表示
    for ( i = 0; i < cnt; i++ ) {
        printf( "%-20s %4d.%2d.%2d\n", lib[i].name, 
            lib[i].date.yy, lib[i].date.mm, lib[i].date.dd );
    }

    return 0;
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:異常終了する原因は構造体変数か 24876 iijima 2005/12/19 22:36:57
<子記事> Re:異常終了する原因は構造体変数か 24877 iijima 2005/12/19 22:43:40
<子記事> Re:異常終了する原因は構造体変数か 24881 nop 2005/12/20 09:45:31


No.24876

Re:異常終了する原因は構造体変数か
投稿者---iijima(2005/12/19 22:36:57)


一見して図書名を保持すべきメモリ領域が確保されていないようですが。


この投稿にコメントする

削除パスワード

No.24877

Re:異常終了する原因は構造体変数か
投稿者---iijima(2005/12/19 22:43:40)


補足。

> 当サイトの15-2の例題をお借りして

当該例題中「図書名(100バイト)」とありますが、あなたのプログラムでは100バイトはどこにあるのかな? ってことです。


この投稿にコメントする

削除パスワード

No.24878

Re:異常終了する原因は構造体変数か
投稿者---あきき(2005/12/19 23:26:18)


>
>当該例題中「図書名(100バイト)」とありますが、あなたのプログラムでは100バイトはどこにあるのかな? ってことです。

やっぱり、配列で宣言しないとだめなんでしょうか。要素数が不確定の場合を想定していたものですから。




この投稿にコメントする

削除パスワード

No.24879

Re:異常終了する原因は構造体変数か
投稿者---επιστημη(2005/12/19 23:36:13)


> 要素数が不確定の場合を想定していたものですから。

想定するのは結構だが、その対処が中途半端。だからコケた。



この投稿にコメントする

削除パスワード

No.24880

Re:異常終了する原因は構造体変数か
投稿者---iijima(2005/12/20 07:32:40)


> 要素数が不確定の場合

それは次の課題ということにして、まずは固定長で完成させてはいかがですか?
チャレンジは大事ですが、一度にたくさんの問題をクリアしようとすると挫折しやすいですよ。
ひとつずつ着実に進んでいくのが良いと思います。


この投稿にコメントする

削除パスワード

No.24881

Re:異常終了する原因は構造体変数か
投稿者---nop(2005/12/20 09:45:31)


>1件入力してENTERキーを押すなり異常終了します。現在、原因究明中です。どなたか、助言の程お願いします。

> struct library {
> char *name;
> struct ymd date;
> };
> lib_t work = {"",0,0,0};
> while (scanf("%s %d %d %d",work.name, &work.date.yy, &work.date.mm, &work.date.dd)!=EOF){

文字列リテラルを書き換えるのはいけません。



この投稿にコメントする

削除パスワード

No.24883

Re:異常終了する原因は構造体変数か
投稿者---あきき(2005/12/20 12:55:46)


>> struct library {
>> char *name;
>> struct ymd date;
>> };
>> lib_t work = {"",0,0,0};
>> while (scanf("%s %d %d %d",work.name, &work.date.yy, &work.date.mm, &work.date.dd)!=EOF){
>
>文字列リテラルを書き換えるのはいけません。

あの、どこで文字列リテラルを書き換えているのでしょうか。


この投稿にコメントする

削除パスワード

No.24885

Re:異常終了する原因は構造体変数か
投稿者---RiSK(2005/12/20 13:50:09)


>>文字列リテラルを書き換えるのはいけません。
>
>あの、どこで文字列リテラルを書き換えているのでしょうか。

ここ。
>>> while (scanf("%s %d %d %d",work.name, &work.date.yy, &work.date.mm, &work.date.dd)!=EOF){

work.name は "" へのポインタを保持していますから,
scanf("%s",work.name); でリテラルを書き換えようとします。


この投稿にコメントする

削除パスワード

No.24886

Re:異常終了する原因は構造体変数か
投稿者---shu(2005/12/20 14:02:52)


lib_t work = {"",0,0,0};

のところは、

lib_t work = {NULL,0,0,0};

とした方するべき。



この投稿にコメントする

削除パスワード

No.24887

Re:異常終了する原因は構造体変数か
投稿者---nop(2005/12/20 14:06:54)


> lib_t work = {NULL,0,0,0};
> とした方するべき。

加えて、

work.name = (char *)malloc( /* サイズ指定 */ );

などとして、領域の確保も必要ですね。


この投稿にコメントする

削除パスワード

No.24888

Re:異常終了する原因は構造体変数か
投稿者---あきき(2005/12/20 15:08:14)


>work.name = (char *)malloc( /* サイズ指定 */ );
>
>などとして、領域の確保も必要ですね。

まだ、malloc()関数を理解していないのでなんともいえないのですが、
プログラムからするとこんなものですか。

work.name の動的領域の確保; 
while( scanf("%s %d %d %d",work.name, &work.date.yy, &work.date.mm, &work.date.dd) != EOF){
    //省略
}



この投稿にコメントする

削除パスワード

No.24889

Re:異常終了する原因は構造体変数か
投稿者---RAPT(2005/12/20 15:59:38)


scanf() で、EOF と比較するよりも、格納された引数の数で
比較した方が良いと思います。

今回は、
while( scanf(/*snip*/) != EOF )
ではなく
while( scanf(/*snip*/) == 4 )
という風に。



この投稿にコメントする

削除パスワード

No.24890

Re:異常終了する原因は構造体変数か
投稿者---iijima(2005/12/20 16:28:53)


> プログラムからするとこんなものですか。

それで動くプログラムはできるでしょうが、確保すべきメモリ領域のサイズはどうやって決めるのですか?

例えば、mallocで確保する領域を100バイトなどと決めてしまうのなら、はじめからwork.nameを固定長の配列としておくのと意味的に変わりありません。

サイズを可変としたいのならば、mallocで確保すべきサイズ(この場合は図書名のバイト数)を先に得る必要があり、それをやろうとするならあちこちいじらなくてはなりません。
# 多分scanfは使えないでしょう。

他にも指摘されていることがあるのですから、ここはひとまずmallocは横に置いて、固定長配列で完成させることに集中するのがよろしいかと。


この投稿にコメントする

削除パスワード

No.24891

申し訳ありません
投稿者---あきき(2005/12/20 17:34:12)


 皆さんからの助言を頂くことで解決できるかなと、当初思っていたのですが、話が膨らみついていくのにやっとです。残念ではありますが、一旦、このレスを中断し、構造体そのものの理解につとめていき、再度このレスについて投稿したいと思います。助言を頂いたにもかかわらずこの様な形で一旦終了する事どうかお許しください。


この投稿にコメントする

削除パスワード

No.24892

Re:申し訳ありません
投稿者---REE(2005/12/20 19:32:05)


> 皆さんからの助言を頂くことで解決できるかなと、当初思っていたのですが、話が膨らみついていくのにやっとです。残念ではありますが、一旦、このレスを中断し、構造体そのものの理解につとめていき、再度このレスについて投稿したいと思います。助言を頂いたにもかかわらずこの様な形で一旦終了する事どうかお許しください。

あなたは勘違いしています。
話が膨らんでいるとおっしゃっていますが、全てのコメントは、
char *nameに関するものです。
また、今回の問題は、構造体とは直接関係ありません。
よって、構造体をいくら理解しても解決しません。



この投稿にコメントする

削除パスワード

No.24893

Re:申し訳ありません
投稿者---あきき(2005/12/20 21:46:15)


>また、今回の問題は、構造体とは直接関係ありません。
>よって、構造体をいくら理解しても解決しません。

私が勘違いしている内容を指摘して頂きありがとうございます。




この投稿にコメントする

削除パスワード

No.24894

Re:申し訳ありません
投稿者---fuku(2005/12/21 11:30:50)


>私が勘違いしている内容を指摘して頂きありがとうございます。
>
ポインタと文字列について調べればよろしいかと
当サイトの10章3節




この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧