掲示板利用宣言

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

 私は

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

掲示板2

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

No.29125

C言語の配列入力条件について
投稿者---とむ(2006/12/01 21:02:36)


下記の探索のプログラムに入力した文字、英大文字11文字の場合の時だけ探索し、それ以外のときは再入力を行うようにしたいのですが、わかりません。よろしくおねがいします。



#include  <stdio.h>
#include  <string.h>
#include  <limits.h>

int bm_match(const char txt[], const char pat[])
{
    int  pt;        
    int  pp;        
    int  txt_len = strlen(txt);        
    int  pat_len = strlen(pat);        
    int  skip[UCHAR_MAX + 1];                

    for (pt = 0; pt <= UCHAR_MAX; pt++)  
        skip[pt] = pat_len;
    for (pt = 0; pt < pat_len - 1; pt++)
        skip[pat[pt]] = pat_len - pt - 1;
                                        
    while (pt < txt_len) {
        pp = pat_len - 1;               

        while (txt[pt] == pat[pp]) {
            if (pp == 0)
                return (pt);
            pp--;
            pt--;
        }
        pt += skip[txt[pt]];
    }

    return (-1);
}

int main(void)
{
    int   idx;
    char  s1[80];      
    char  s2[80];      

    printf("テキスト:");
    scanf("%s", s1);

    printf("パターン:");
    scanf("%s", s2);

    idx = bm_match(s1, s2); 

    if (idx == -1)
        puts("テキスト中にパターンは存在しません。");
    else
        printf("%d文字目に見つかりました。\n", idx + 1);

    return (0);
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:C言語の配列入力条件について 29126 yoh2 2006/12/01 22:39:21
<子記事> Re:C言語の配列入力条件について 29128 かずま 2006/12/02 14:03:04


No.29126

Re:C言語の配列入力条件について
投稿者---yoh2(2006/12/01 22:39:21)


テキストとパターンのどちらを11文字の英大文字にしたいかは分かりませんが、
どちらにしても望みの文字列が得られるまで入力部分をループさせるとよいです。
#define VALID_STR_LEN   11

/* 英大文字11文字なら非ゼロ、それ以外では0を返す */
int is_valid_str(const char str[])
{
    size_t i;

    for(i = 0; i < VALID_STR_LEN; i++){
        if(!isupper(str[i])){
            return 0;
        }
    }

    return str[VALID_STR_LEN] == '\0';
}

int main(void)
{
   ...

    /* 「str」はs1かs2 */
    for(;;){
        printf("(テキスト or パターン)");
        scanf("%s", str);
        if(is_valid_str(str)){
            break;
        }
        printf("文字列が不正です。\n");
    }

   ...
}


不正文字列の時のエラーメッセージが必要ないなら、ループ部分がもう少し単純になります。
    do{
        printf("(テキスト or パターン)");
        scanf("%s", str);
    }while(is_valid_str(str));



この投稿にコメントする

削除パスワード

No.29127

Re:C言語の配列入力条件について
投稿者---とむ(2006/12/02 00:35:16)


>テキストとパターンのどちらを11文字の英大文字にしたいかは分かりませんが、
>どちらにしても望みの文字列が得られるまで入力部分をループさせるとよいです。
><pre>
#define VALID_STR_LEN 11

/* 英大文字11文字なら非ゼロ、それ以外では0を返す */
int is_valid_str(const char str[])
{
size_t i;

for(i = 0; i < VALID_STR_LEN; i++){
if(!isupper(str[i])){
return 0;
}
}

return str[VALID_STR_LEN] == '\0';
}

int main(void)
{
...

/* 「str」はs1かs2 */
for(;;){
printf("(テキスト or パターン)");
scanf("%s", str);
if(is_valid_str(str)){
break;
}
printf("文字列が不正です。\n");
}

...
}</pre>
>
>不正文字列の時のエラーメッセージが必要ないなら、ループ部分がもう少し単純になります。
><pre> do{
printf("(テキスト or パターン)");
scanf("%s", str);
}while(is_valid_str(str));</pre>


なるほど、私はif(!=)でしようと思いましたが、こっちの方がいいですね
わかりやすいです。わざわざありがとうございました。



この投稿にコメントする

削除パスワード

No.29128

Re:C言語の配列入力条件について
投稿者---かずま(2006/12/02 14:03:04)


> 下記の探索のプログラムに入力した文字、英大文字11文字の場合の時
> だけ探索し、それ以外のときは再入力を行うようにしたいのですが、
    char buf[1024], c;

    for (;;) {
        printf("テキスト:");
        if (!fgets(buf, sizeof buf, stdin)) return 1;
        if (sscanf(buf, " %11[A-Z] %c", s1, &c) == 1) break;
        puts("文字列が不正です。");
    }

ただし、Borland のコンパイラは scanf の %[ の処理にバグがあるので、
次のようにして回避しないといけません。
    for (;;) {
        printf("テキスト:");
        if (!fgets(buf, sizeof buf, stdin)) return 1;
        *s1 = '\0';
        if (sscanf(buf, " %11[A-Z] %c", s1, &c) == 1 && *s1) break;
        puts("文字列が不正です。");
    }



この投稿にコメントする

削除パスワード

No.29129

Re:C言語の配列入力条件について
投稿者---かずま(2006/12/02 14:31:30)


>       if (sscanf(buf, " %11[A-Z] %c", s1, &c) == 1) break;
すみません。これだと、11文字以下になりますね。
11文字ちょうどに限定したいのなら、
    char buf[1024], c;  int n;

    for (;;) {
        printf("テキスト:");
        if (!fgets(buf, sizeof buf, stdin)) return 1;
        if (sscanf(buf, " %11[A-Z]%n %c", s1, &n, &c)==1 && n==11) break;
        puts("入力文字列が不正です。");
    }

ただし、LSI C-86 は %n のバグのため、これではだめです。


この投稿にコメントする

削除パスワード

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