C言語関係掲示板

過去ログ

No.278.「%%,」と「%%」ではさまれたキーワードの抜き出し

[戻る] [ホームページ]


No.1668

読み込んだテキストについて
投稿者---べる(2002/06/06 13:47:56)


はじめまして!
今までここの掲示板を見てきましたが、
たいへん役に立っています。

ところで質問があります。
読み込んだテキストの中に例えば、
・・・%%,キーワード1%%・・・・・・・・・・・・・・・
・・・・・・・・・・%%,キーワード2%%・・・・・・・・
・%%,キーワード3%%・・・・・・・・・・・・・・・・・
と入っているとします。

その%%,%%で囲まれたキーワード1〜だけを抜き出すには
どうしたらよいのでしょうか?

No.1670

Re:読み込んだテキストについて
投稿者---かずま(2002/06/06 14:44:58)


> その%%,%%で囲まれたキーワード1〜だけを抜き出すにはどうしたらよいのでしょうか?

「%%,」と「%%」ではさまれた「キーワード1」、「キーワード2」、「キーワード3」を
抜き出すということでよろしいでしょうか。

私がすぐに思いついたのは、状態遷移を利用する方法です。
有限オートマトン、ああ、なんと懐かしい響き。

他の人の解を期待します。
#include <stdio.h>

int get_keyword(FILE *fp, char *keyword, int size)
{
    int c, i, state = 0;

    do {
        if ((c = getc(fp)) == EOF) return 0;
        switch (state) {
        case 0: if (c == '%') state = 1; break;
        case 1: state = (c == '%') ? 2 : 0; break;
        case 2: state = (c == ',') ? 3 : (c == '%') ? 1 : 0; break;
        }
    } while (state != 3);
    --size;
    do {
        if ((c = getc(fp)) == EOF) return 0;
        switch (state) {
        case 3:
            if (c == '%')
                state = 4;
            else
                if (i < size) keyword[i++] = c;
            break;
        case 4:
            if (c == '%')
                state = 5;
            else {
                if (i < size) keyword[i++] = '%';
                if (i < size) keyword[i++] = c;
                state = 3;
            }
            break;
        }
    } while (state != 5);
    keyword[i] = '\0';
    return 1;
}

int main()
{
    char keyword[256];

    while (get_keyword(stdin, keyword, sizeof keyword))
        puts(keyword);
    return 0;
}


No.1671

Re:読み込んだテキストについて
投稿者---べる(2002/06/06 15:09:35)


かずま様、早急な回答、誠にありがとうございます。

>「%%,」と「%%」ではさまれた「キーワード1」、「キーワード2」、「キーワード3」を
>抜き出すということでよろしいでしょうか。
そのとおりです。

かずま様から提示頂いたプログラムをこれから理解し、
実行したいと思います。
ありがとうございました。


No.1672

Re:読み込んだテキストについて
投稿者---かずま(2002/06/06 18:24:31)


> かずま様から提示頂いたプログラムをこれから理解し、実行したいと思います。

このプログラム、バグがあります。
get_keyword の最初の、int c, i, state = 0; の i を 0 で初期化するのを忘れていました。

これだけでは何ですので、別のやり方を添付します。
#include <stdio.h>

int ch_buf[4];
int index = 0;

int get_ch(FILE *fp)
{
    if (index)
        return ch_buf[--index];
    return getc(fp);
}

void unget_ch(int c)
{
    ch_buf[index++] = c;
}

enum { START = 256, STOP };

int get_token(FILE *fp)
{
    int c;

    if ((c = get_ch(fp)) != '%') return c;
    if ((c = get_ch(fp)) != '%') { unget_ch(c); return '%'; }
    if ((c = get_ch(fp)) != ',') { unget_ch(c); return STOP; }
    return START;
}

int get_keyword(FILE *fp, char *keyword, int size)
{
    int t, i = 0;

    do {
        if ((t = get_token(fp)) == EOF) return 0;
    } while (t != START);
    --size;
    for (;;) {
        if ((t = get_token(fp)) == EOF) return 0;
        if (t == STOP)
            break;
        if (i < size) keyword[i++] = t;
    }
    keyword[i] = '\0';
    return 1;
}

int main()
{
    char keyword[256];

    while (get_keyword(stdin, keyword, sizeof keyword))
        puts(keyword);
    return 0;
}