掲示板利用宣言

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

 私は

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

掲示板2

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

No.25239

部分文字列を見つける
投稿者---momo(2006/01/12 14:13:15)


初心的な質問で申し訳ないのですが、行き詰っております。

文字列A中に部分文字列Bを含んでいる場合を取得したいと思っています。
ここで、部分文字列Bを含んでいる場合であっても、コメントは除外したいので、
部分文字列Bよりも前に"#"がある場合は無視するようにしたいのですが、
この「部分文字列Bよりも前に"#"がある場合」の取得をどのようにすれば良いか思いつきません。

何か良い方法、関数などありましたら教えて下さい。
環境は UNIX C です。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:部分文字列を見つける 25240 Blue 2006/01/12 14:25:57
<子記事> Re:部分文字列を見つける 25242 nop 2006/01/12 14:41:34


No.25240

Re:部分文字列を見つける
投稿者---Blue(2006/01/12 14:25:57)


コメントとは行コメントでしょうか?

単純に文字列を検索するには strstr という関数があります。


この投稿にコメントする

削除パスワード

No.25241

Re:部分文字列を見つける
投稿者---momo(2006/01/12 14:40:05)


回答ありがとうございます。

>コメントとは行コメントでしょうか?
はい。例えば、"xyz"という部分文字列を持つ行のみ取得したいのですが、

1: aaaaaxyzbbb
2: aaaaabbbbb
3: aaaaa xyz bbb
4: (空行)
5: #aaaxyzbbb
6: aaaxyzbbb #ccccc

上で、1,3,6行目のみ取得して、2,4,5行目のようなものは無視したいと思っています。

strstr()で"xyz"と"#"の有無を取得したとして、この2つの位置関係をどのように取得するかで行き詰っております。

お知恵を貸していただければと思います。


この投稿にコメントする

削除パスワード

No.25243

Re:部分文字列を見つける
投稿者---かずま(2006/01/12 14:52:14)


> strstr()で"xyz"と"#"の有無を取得したとして、この2つの位置関係を
> どのように取得するかで行き詰っております。

位置関係ならポインタの比較ですみます。
#include <stdio.h>
#include <string.h>

char *a[] = {
    "1: aaaaaxyzbbb",
    "2: aaaaabbbbb",
    "3: aaaaa xyz bbb",
    "4: (空行)",
    "5: #aaaxyzbbb",
    "6: aaaxyzbbb #ccccc",
};

char *find(const char *s1, const char *s2)
{
    char *p, *q = strstr(s1, s2);
    return (!q || (p = strchr(s1, '#')) && p < q) ? NULL : q;
}

int main(void)
{
    int i;
    for (i = 0; i < sizeof(a)/sizeof(*a); i++)
        printf("%s [xyz] in [%s]\n", find(a[i], "xyz") ? "  " : "no", a[i]);
    return 0;
}



この投稿にコメントする

削除パスワード

No.25244

Re:部分文字列を見つける
投稿者---Blue(2006/01/12 14:53:52)


>1: aaaaaxyzbbb
>2: aaaaabbbbb
>3: aaaaa xyz bbb
>4: (空行)
>5: #aaaxyzbbb
>6: aaaxyzbbb #ccccc
この状態で文字列バッファに持っているとちょっと厄介ですね。
# テキストファイルでfgetsで読み込むなら簡単ですが。

まず、1行の文字列を取得(\nまでを取得)して(strtok等)、その文字列に対してまずは'#'を探す。(strchr)
nopさんのおっしゃるやり方を使わせてもらい、'#'を'\0'に書き換える。
それから、strstrで目的の文字列を探す。

という方法でしょうか。

もっとも、元の文字列をバッファを解さずに処理するならば、地道に先頭から一文字一文字検索していくのが確実でしょう。



この投稿にコメントする

削除パスワード

No.25242

Re:部分文字列を見つける
投稿者---nop(2006/01/12 14:41:34)


>部分文字列Bよりも前に"#"がある場合は無視するようにしたいのですが、
>この「部分文字列Bよりも前に"#"がある場合」の取得をどのようにすれば良いか思いつきません。

文字列を変更してもよいのであれば、
最初に見つかった'#'を'\0'にしてから検索するとよいでしょう。
文字列を変更するとまずい場合は、
別バッファにコピーして処理を行うとよいでしょう。


この投稿にコメントする

削除パスワード

No.25245

Re:部分文字列を見つける
投稿者---momo(2006/01/12 15:27:14)


>この状態で文字列バッファに持っているとちょっと厄介ですね。
># テキストファイルでfgetsで読み込むなら簡単ですが。
申し訳ありません。元データはfgets()でファイルから読み込みます。
読込んだ1行はそのままfputs()で出力しようと思っているので直接操作できませんが、
添付バッファにコピーするなどは自由にできます。
情報提示に不備がありました。申し訳ありませんでした。

Blue様とnop様の方法は大変分かりやすく簡単に実現できると思いますので試してみます。

かずま様の方法
> char *p, *q = strstr(s1, s2);
> return (!q || (p = strchr(s1, '#')) && p < q) ? NULL : q;
において、"#"が部分文字列の前にある場合、p < q は必ず保障されるのでしょうか?
この確信が調べきれなかったので今回投稿させてもらったのですが、もし保障されるのであれば、
かずま様の方法を使用させてもらいたいと思っております。
いかがでしょうか?



この投稿にコメントする

削除パスワード

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