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

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

 詳しくはこちら



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

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


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

No.19440

Switch文のループ処理?
投稿者---Kei(2005/01/24 15:53:44)


Switch文で1つの処理を行い、
その処理で取得した値を使用して同じSwitch文
で別の処理を行いたいのですが、どういう風に書けばよいのか分かりません。
説明が至らないかもしれませんが下に処理したい概要を書いたのでわかる方がいたらアドバイスをお願いします。

main()
{
    char menu_select[64+1];
    scanf("%s", &menu_select);
    select(menu_select);
}


int select(menu_select)
{
    switch(atoi(menu_select)){
        case 1:
            処理A
            値1を取得
            値が取得できなかったらSwitch文を最初から行なう
        case 2:
            処理Aで取得した値1で処理B
            処理Aが行なわれていなければmain関数からselect関数を再度コールする
    }
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:Switch文のループ処理? 19444 れいじ 2005/01/24 18:42:35
<子記事> Re:Switch文のループ処理? 19445 Craft 2005/01/24 19:00:06
<子記事> Re:Switch文のループ処理? 19446 ぽへぇ 2005/01/24 19:02:15


No.19444

Re:Switch文のループ処理?
投稿者---れいじ(2005/01/24 18:42:35)


>Switch文で1つの処理を行い、
>その処理で取得した値を使用して同じSwitch文
>で別の処理を行いたいのですが、どういう風に書けばよいのか分かりません。
>説明が至らないかもしれませんが下に処理したい概要を書いたのでわかる方がいたらアドバイスをお願いします。
>
>
main()
{
    char menu_select[64+1];
    scanf("%s", &menu_select);
    select(menu_select);
}


int select(menu_select)
{
    switch(atoi(menu_select)){
        case 1:
            処理A
            値1を取得
            値が取得できなかったらSwitch文を最初から行なう
        case 2:
            処理Aで取得した値1で処理B
            処理Aが行なわれていなければmain関数からselect関数を再度コールする
    }
}



switch文を使用すると、caseで条件分岐をすることから、case 1:内での処理で設定した変数をcase 2:で使用することはできません。
詳しくいうと、case文は一つのcase内の処理が行われたら、switch文から抜けるからです。
なので、上記のご質問のような文は記述できません。

別の方法で実現するしかありません。


この投稿にコメントする

削除パスワード

No.19447

Re:Switch文のループ処理?
投稿者---Craft(2005/01/24 19:07:28)


>switch文を使用すると、caseで条件分岐をすることから、case 1:内での処理で設定した変数をcase 2:で使用することはできません。
>詳しくいうと、case文は一つのcase内の処理が行われたら、switch文から抜けるからです。
>なので、上記のご質問のような文は記述できません。
>
>別の方法で実現するしかありません。

そんなことはないです。
switch〜caseは、breakしないかぎり延々と継続する命令を処理していきます。
以下のプログラムで1を入力すると、case 1:とcase 2:が連続で実行されます。
#include <stdio.h>

int main(void)
{
    int n, c = 0;
    
    scanf("%d",&n);
   
    switch(n){
        case 1:
            printf("path-1\n");
            c = 1;
        case 2:
            printf("path-2 c=%d\n", c );
            break;
        case 3:
            printf("path-3 c=%d\n", c );
            break;
        default:
            printf("default c=%d\n", c );
            break;
    }

    return 0;
}



この投稿にコメントする

削除パスワード

No.19445

Re:Switch文のループ処理?
投稿者---Craft(2005/01/24 19:00:06)


>Switch文で1つの処理を行い、
>その処理で取得した値を使用して同じSwitch文
>で別の処理を行いたいのですが、どういう風に書けばよいのか分かりません。

繰り返し判定をするための変数を1つもうけて、以下のようにdo〜while()にするという手もあります。(do〜whileは1回以上ループする)
判定用の変数のリセット(cont=0とか)を忘れると永久ループするので気をつけてください。

int select(char *,int *);
main()
{
    int cont;
    char menu_select[64+1];
    scanf("%s", &menu_select);

    /* 繰り返しが必要な間はループ */
    do{
        cont = 0;  /* 処理開始時は繰り返さないようにしておく */
        select(menu_select,&cont);
        /* select()がcont==1(継続)を返した場合は、もう一度select()を呼ぶ */
    }while( cont == 1 );
}


int select(char *menu_select,int *pcont)
{
    int sw_cont;

    /* switchを繰り返す必要がある間は継続 */
    do{
        sw_cont = 0;      /* 処理開始時は繰り返さないようにしておく */
        switch(atoi(menu_select)){
            case 1:
                処理A
                値1を取得
                値が取得できなかったらSwitch文を最初から行なう
                if( 値が取得できなかった ){
                    sw_cont = 1;   /* もう一度やるので1にする */
                    break;
                }
            case 2:
                処理Aで取得した値1で処理B
                処理Aが行なわれていなければmain関数からselect関数を再度コールする
                if( atoi(menu_select) == 1 ){
                    /* atoi(menu_select) == 1 で判断する場合 */
                    *pcont = 1;
                    break;
                }
        }

        /* sw_contが1だった場合は、もう一度switchを処理する */
    }while( sw_cont == 1 );

    return 0;
}



この投稿にコメントする

削除パスワード

No.19465

何度もすみません。
投稿者---Kei(2005/01/25 12:08:38)


Craftさんのサンプルを参考に自分なりに組んで見たのですが、
スイッチ用のカウンタ(sw_cnt)とディレクトリパス(dir_path_buf)
が保持されません。どこが悪いのか指摘をお願いします。
何度もすみません。

void main(int argc, char *argv[])
{
    char menu_select[MAX_STRING];      /* メニュー選択用変数 */

    int i = 0;
    int ret = 0;                        /* 関数戻値変数 */
    
    /* メニュー選択変数初期化 */
    memset(menu_select, '\0', sizeof(menu_select)); 

    char *menu_name[MENU] = { "1.フォルダ選択", "2.ファイル一覧", "3.ファイル情報詳細", "4.ファイル編集", "5.終了" };

    printf("■メインメニュー\n");
    for(i = 0; i < MENU; i++){
        printf("  %s\n", menu_name[i]);
    }

    printf("行ないたい作業のNoを入力し、Enterキーを押してください。\n");
    scanf("%s", &menu_select);
    getchar();

    /* メニュー関数呼び出し */
    ret = menu(menu_select);
    if(ret != OK){
        while(1){
            for(i = 0; i < MENU; i++){
                printf("  %s\n", menu_name[i]);
            }
            printf("行ないたい作業のNoを入力し、Enterキーを押してください。\n");
            scanf("%s", &menu_select);
            getchar();
            /* 5が入力されるまでループ */
            ret = menu(menu_select);
            if(ret == OK){
                break;
            }
        }
    }
    exit(1);
}
/* メニュ−表示関数 */
int menu(char *menu_select)
{
    char dir_path[MAX_STRING];    /* ディレクトリパス用 */
    char dir_path_buf[MAX_STRING];  /* ディレクトリパス用 */
    int sw_cnt;
    int ret = 0;                    /* 関数戻値変数 */

    printf("セレクトNo:%s\n", menu_select);
    do{
        switch(atoi(menu_select)){
            case 1:
                printf("フォルダのパスを指定してください。\n");
                printf("0でメニューへ、5で終了します。\n");
                /* ディレクトリパス変数初期化 */
                memset(dir_path, '\0', sizeof(dir_path));
                scanf("%s", &dir_path);
                /* 5が入力されたら終了 */
                if(strcmp(dir_path, "5") == OK){
                    return OK;
                /* 0が入力されたらメニュー */
                } else if(strcmp(dir_path, "0") == OK){
                    ret = menu("0");
                    if(ret != OK){
                        return NG;
                    }
                } else {
                    /* ディレクトリのパスチェック */
                    ret = chk_path(dir_path);
                    if(ret == OK){
                        /* ディレクトリのパスが存在したらパスを引数にしてメニュー表示 */
                        /* ディレクトリパスをファイル一覧関数用変数にコピ− */
                        memset(dir_path_buf, '\0', sizeof(dir_path_buf));
                        strcpy(dir_path_buf, dir_path);
                        /* case2を選択できるフラグを立てる */
                        sw_cnt = 2;
                        printf("カウンタ:%d\n", sw_cnt);
                        printf("引数:%s\n", dir_path_buf);
                        ret = menu("0");
                        if(ret != OK){
                            return NG;
                        }
                    } else {
                        /* ディレクトリのパスが存在しなかったらメニュー表示 */
                        sw_cnt = -1;
                        ret = menu("0");
                        if(ret != OK){
                            return NG;
                        }
                    }
                    break;
                }
            case 2:
                if(sw_cnt == 2){
                    printf("ディレクトリパス:%s\n", dir_path_buf);
                    /* case1で取得したディレクトリパスを引数ディレクトリ内のファイル一覧を表示させる関数を呼ぶ */
                    ret = folder(dir_path_buf);
                    if(ret != NG){
                        printf("フォルダが指定されていないので一覧の取得出来ません。\n");
                        return NG;
                    }
                    sw_cnt = 3;
                }else{
                    printf("フォルダが指定されていないので一覧の取得出来ません。\n");
                }
                return NG;
            case 3:
                if(sw_cnt == 3){
                    //ファイル詳細情報関数コール
                }else{
                    printf("ファイルが選択されていないので情報の取得が出来ません。\n");
                }
                return NG;
                break;
            case 4:
                if(sw_cnt == 3){
                    //ファイル編集関数コール
                }else{
                    printf("ファイルが選択されていないので編集できません。\n");
                }
                return NG;
                break;
            case 5:
                printf("終了します。\n");
                return OK;
            default:
                printf("メインメニューの1〜5を選択してください。\n");
                return NG;
            }
        }while(1);
    return OK;
}




この投稿にコメントする

削除パスワード

No.19469

Re:何度もすみません。
投稿者---Craft(2005/01/25 13:31:39)


>Craftさんのサンプルを参考に自分なりに組んで見たのですが、
>スイッチ用のカウンタ(sw_cnt)とディレクトリパス(dir_path_buf)
>が保持されません。どこが悪いのか指摘をお願いします。

case 1: で情報表示後、sw_cnt に 2をいれて、case 2:にいくことを期待していると思われますが、[→]で示したところにbreakがあるので、値は入っても、case 2:にいかずに switch文を抜けてしまいます。
なので、これが原因です。

                    /* ディレクトリのパスチェック */
                    ret = chk_path(dir_path);
                    if(ret == OK){
                        /* ディレクトリのパスが存在したらパスを引数にしてメニュー表示 */
                        /* ディレクトリパスをファイル一覧関数用変数にコピ− */
                        memset(dir_path_buf, '\0', sizeof(dir_path_buf));
                        strcpy(dir_path_buf, dir_path);
                        /* case2を選択できるフラグを立てる */
                        sw_cnt = 2;
                        printf("カウンタ:%d\n", sw_cnt);
                        printf("引数:%s\n", dir_path_buf);
                        ret = menu("0");
                        if(ret != OK){
                            return NG;
                        }
                    } else {
                        sw_cnt = -1;
                        ret = menu("0");
                        if(ret != OK){
                            return NG;
                        }
                    }
 ここ→             break;


あと、return 文のあとに break 文がありますが、実行されないので、こういうのは消しましょう。


この投稿にコメントする

削除パスワード

No.19471

勘違いだったらすみません。
投稿者---Kei(2005/01/25 14:19:27)


いろいろとありがとうございます。
sw_cntを2にした後再度メニューを表示させたいので
menu関数に0を渡して再度コールしているのですが、
関数を再度コールしても値は保持されるで宜しいのでしょうか?


                    /* ディレクトリのパスチェック */
                    ret = chk_path(dir_path);
                    if(ret == OK){
                        /* ディレクトリのパスが存在したらパスを引数にしてメニュー表示 */
                        /* ディレクトリパスをファイル一覧関数用変数にコピ− */
                        memset(dir_path_buf, '\0', sizeof(dir_path_buf));
                        strcpy(dir_path_buf, dir_path);
                        /* case2を選択できるフラグを立てる */
                        sw_cnt = 2;
                        printf("カウンタ:%d\n", sw_cnt);
                        printf("引数:%s\n", dir_path_buf);
→ここでメニュー表示    ret = menu("0");
                        if(ret != OK){
                            return NG;
                        }
                    } else {
                        sw_cnt = -1;
                        ret = menu("0");
                        if(ret != OK){
                            return NG;
                        }
                    }
                    break;






この投稿にコメントする

削除パスワード

No.19472

Re:勘違いだったらすみません。
投稿者---Craft(2005/01/25 14:27:57)


>いろいろとありがとうございます。
>sw_cntを2にした後再度メニューを表示させたいので
>menu関数に0を渡して再度コールしているのですが、
>関数を再度コールしても値は保持されるで宜しいのでしょうか?

menu()からmenu()を呼ぶ再帰型で値を保持したい場合は、変数宣言に static をつけないと保持されません。
以下が再帰関数で値を保持し続ける例です。

void func( void )
{
    static num = 0;

    if( num == 5 ){
        return;
    }
    else{
       num = num + 1;
       printf( "num = %d\n", num );
       func();
    }
}



この投稿にコメントする

削除パスワード

No.19473

ありがとうございました。
投稿者---Kei(2005/01/25 14:45:48)


ありがとうございました。
おかげさまで、自分のやりたい動作をしてくれました。

また何かあったらよろしくお願いします。


この投稿にコメントする

削除パスワード

No.19446

Re:Switch文のループ処理?
投稿者---ぽへぇ(2005/01/24 19:02:15)


>case 1:
>   処理A
>   値1を取得
>   値が取得できなかったらSwitch文を最初から行なう

switch を、ですか? atoi(menu_select)の結果は
何回繰り返そうと1のままですから、処理Aを繰り返す、
ということになります。処理Aの結果、値1が変わることは
あるのでしょうか?

また、処理Aが終わったらmainはどうするのでしょう?。
(以下のプログラムでは処理A後、プログラム終了)

-------------
#include    <stdio.h>

#define Length   (64)
int select(int menu_select);

int main(void)
{
    char    menu_str[Length+1];
    int  menu_selct;
    int  retry;

    do {
        fgets(menu_str, Length, stdin);
        sscanf(menu_str, "%d", &menu_select);
        retry = select(menu_select);
    } while (retry);

    return 0;
}


int select(int menu_select)
{
    static int doneA = 0;
    static int val1 = 0;
    int  retry = 0;

    switch(menu_select){
        case 1:
            do {
                処理A();
            } while ( !GetVal1(&val1) );
            doneA = 1;
            break;

        case 2:
            if(doneA) {
                処理B(val1);
            } else {
                retry = 1;
            }
            break;

        default:
            retry = 1;
            break;
    }

    return retry;
}





この投稿にコメントする

削除パスワード

No.19453

Re:Switch文のループ処理?
投稿者---Kei(2005/01/24 21:13:31)


たくさんのレスありがとうございます。

やりたい事は、
main関数内で配列でメニューっぽいものを出し
そこで画面から入力した値を引数に
別関数の問題のところ)でcase1、case2、その他に分岐させて
case1で画面からディレクトリのパスを入力し
case2でcase1で取得したパスを元にファイル検索
それ以外はまたメニューに戻るみたいな感じのを組みたかったのですが、

Craftさんのdo〜while案でもう一度やってみようかと思います。
レスを下さった皆様ありがとうございました。

ここは親切な人が多いので非常に助かります。




この投稿にコメントする

削除パスワード

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