←検索窓の楽しみ方
  ショッピングモール  掲示板ランキング


【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら



 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板1こちら


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

No.3572

入力制限のある文字入力について
投稿者---magaimono(2005/03/22 22:26:33)


初めて投稿します。

現在、C言語で社員情報を管理するプログラムを作っています。
入力された文字が制限字数以上であれば再度入力、
制限字数以内であれば入力完了という仕様にしたいので、
fgetsとdo-whileを使ってプログラムを作ろうとしたのですが、
文字を入力しようとした際、入力待ちの状態にならず、文字を入力
することができません。
何故、文字を入力することができないのか全くわかりません。
どなたか教えて下さい。よろしくお願いします。
以下がその部分のプログラムになります。

//main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NAMESIZE_MAX 20

struct Staffdata
{
        char name[NAMESIZE_MAX]; // 名前
        struct Staffdata *next; // 次のデータへのポインタ
};

// 関数のプロトタイプ
struct Staffdata *add_list(struct Staffdata *head);
void Displaydata(struct Staffdata *p);
void Freedata(struct Staffdata *p);

int main(void)
{
        struct Staffdata *head; // 先頭ポインタ 
        int n,id=0;
        head = NULL; // 先頭ポインタにNULLを設定 

        while(1){
                // 社員情報の入力 
                printf("メニュー\n");
                printf("1:社員情報の追加 2:登録情報の表示 3:入力処理の終了\n");
                scanf("%d",&n);
                
                switch(n){
                case 1:
                // リストにデータを登録 
                        head = add_list(head);
                        break;
                case 2:
                // リストの表示 
                        Displaydata(head);
                        break;
                case 3:
                // リストの開放 
                Freedata(head);
                exit(0);
                break;

                default:
                printf("範囲外の番号です.再入力してください.\n");
                continue;
                }             
       }     
       return 0;
}

// リストにデータを登録 
struct Staffdata *add_list(struct Staffdata *head)
{
        struct Staffdata *p, *new_p;
        char str[NAMESIZE_MAX];
        
        // 新規リストにデータを登録 
        if((new_p=(struct Staffdata*)malloc(sizeof(struct Staffdata)))==NULL){
                printf("Memory error.\n");
        free(new_p);
                exit(1);
        }
        
        p=head;
        
        do{
            printf("名前を入力\n");
            fgets(str,21,stdin);
            str[strlen(str)-1]='\0';
            printf("%d\n",strlen(str));
            if(strlen(str)>(NAMESIZE_MAX))
            {
                printf("名前が制限文字数(20文字)を越えました.再度,入力してください.\n");
            }
        } while(strlen(str)>=NAMESIZE_MAX);
        
        strcpy(new_p->name,str);
        
        // ポインタのつなぎ換え
        new_p->next = head;    
        head = new_p;         
    
        return head;
}

// 登録した社員情報の表示
void Displaydata(struct Staffdata *p)
{
    printf( "登録した社員情報:\n" );
    while (p!= NULL) // 次ポインタがNULLまで処理
    {
        
        printf("名前:%s\n",p->name);
        
        p = p->next;
    }
}

// リストの開放
void Freedata(struct Staffdata *p )
{
        struct Staffdata *p2;

        while (p!= NULL) {     // 次ポインタがNULLまで処理
                p2 = p->next;
                free(p);
                p = p2;
        }
}





この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:入力制限のある文字入力について 3573 Blue 2005/03/22 22:58:41
<子記事> Re:入力制限のある文字入力について 3575 ぽこ 2005/03/22 23:58:40
<子記事> Re:入力制限のある文字入力について 3582 まきじ 2005/03/23 17:47:34


No.3573

Re:入力制限のある文字入力について
投稿者---Blue(2005/03/22 22:58:41)


>char str[NAMESIZE_MAX];
>fgets(str,21,stdin);
バッファサイズは同じにしましょう。



fgetsは格納文字を超えると\0を最後に入れます。
例) 
#include <stdio.h>

int main( void )
{
    char str[ 5 ];
    puts( "入力してください" );
    fgets( str, sizeof( str ), stdin );
    puts( str );
    return 0;
}

実行結果
入力してください
もじれつ
もじ
よって strlenは必ずsizeof( str )以下になります。 入力文字がオーバーかどうかはfgetsで取得した文字列の中に改行文字('\n')があるかで判定します。 (再入力する際はバッファに残った文字列をクリアする必要があります)




この投稿にコメントする

削除パスワード

No.3574

Re:入力制限のある文字入力について
投稿者---Blue(2005/03/22 23:23:28)


入力部分だけ書いてみました。(とういか、ほかの部分見ていない)
バッファサイズが20である場合、有効文字は18文字(改行文字+終端文字)です。

#include <stdio.h> #include <string.h> #define NAMESIZE_MAX 20 int main( void ) { char str[ NAMESIZE_MAX ]; char* p; char c; printf( "名前を入力してください。(%d文字以内)\n", NAMESIZE_MAX - 2 ); while ( 1 ) { /* 入力の取得 */ fgets( str, sizeof( str ), stdin ); /* 改行文字位置取得 */ p = strchr( str, '\n' ); /* 改行文字が存在した場合 */ if ( p != NULL ) { /* 改行文字を終端文字に変換 */ *p = '\0'; break; } /* バッファのクリア */ while ( ( c = getchar() ) != '\n' ) { if ( c == EOF ) { break; } } printf( "入力文字数が%d文字を超えています。再入力してください\n", NAMESIZE_MAX - 2 ); } printf( "名前:%s\n", str ); return 0; }




この投稿にコメントする

削除パスワード

No.3575

Re:入力制限のある文字入力について
投稿者---ぽこ(2005/03/22 23:58:40)


>何故、文字を入力することができないのか全くわかりません。
>どなたか教えて下さい。よろしくお願いします。

原因は二つあります。
一つは、下の継続条件がおかしいことです。

> do{
>(略)
> } while(strlen(str)>=NAMESIZE_MAX);

もう一つは、scanf()とfgets()を併用していることです。
これは併用するなと言うわけではなく、併用する際に注意が必要と言うことです。
#ここのホームページのどっかにあったと思ったんだけど、見つけられなかった。。(-_-;)


この投稿にコメントする

削除パスワード

No.3582

Re:入力制限のある文字入力について
投稿者---まきじ(2005/03/23 17:47:34)


>// 社員情報の入力 
>printf("1:社員情報の追加 2:登録情報の表示 3:入力処理の終了\n");
>scanf("%d",&n);

scanf("%d%*c",&n);

あるいは

scanf("%d%",&n);
rewind(stdin)




この投稿にコメントする

削除パスワード

No.3583

Re:入力制限のある文字入力について
投稿者---RiSK(2005/03/23 22:02:05)


> scanf("%d%",&n);

変換指定が無効です。未定義動作になります

> rewind(stdin)

処理系依存。VC系ならOKですが,今回は環境が明記されてません。


この投稿にコメントする

削除パスワード

No.3586

ありがとうございます
投稿者---magaimono(2005/03/25 02:17:42)


返事が遅れて申し訳ありません.

Blueさん,ぽこさん,まきじさん,Riskさん,皆さんのおかげで
何とか思うような形にすることができました.
ありがとうございます.



この投稿にコメントする

削除パスワード

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




掲示板提供:Real Integrity