C言語関係掲示板

過去ログ

No.573.「----AAAAA----」から「AAAAA」だけを取り出したい

[戻る] [ホームページ]
No.5319

sscanfを使って文字列の抽出
投稿者---つよし(2003/02/21 11:22:09)


sscanfを使用して文字列の中から文字列を取り出したい
のですが、うまくいきません。

「----AAAAA----」という文字列から「AAAAA」だけを取り出したい
のですが、以下の様にsscanfを使ってやったのですが、後ろのハイフン
「-」も一緒にきてしまいます。
また、ハイフンの間の文字列は、可変です。

sscanf(buf,"----%s*%[^-]"
sscanf(buf,"----%s*[^-]"

また、
sscanf(buf,"----%*[^-]"
とすると、取得ができません。
「%s」としなくても「%*[^-]」でできると思っていたのですが
私の認識違いでしょか。


No.5320

Re:sscanfを使って文字列の抽出
投稿者---麗(2003/02/21 12:19:56)


sscanf(buf, "%*[-]%[^-]s", save);
…でどうでしょう?

No.5321

ありがとうございます。
投稿者---つよし(2003/02/21 12:58:27)


>sscanf(buf, "%*[-]%[^-]s", save);
>…でどうでしょう?

ありがとうございます。
うまくいきました。


No.5323

Re:sscanfを使って文字列の抽出(もう少し教えて下さい)
投稿者---つよし(2003/02/21 14:19:19)


もう少し教えて下さい。

「----AAAA----」のかたちは、「sscanf(buf,""%*[-]%[^-]s",」
でとりだすことができたのですが、

「----AAA xxxx xxxx----」(xxxxには任意の文字が入ります。)
のかたちだと、「AAA xxxx xxxx」となってしまいます。

if (sscanf(buf,"----%*s %*%*[^-]",str) == 1) || sscanf(buf,""%*[-]%[^-]s",str) == 1)
if (sscanf(buf,"%*[-]%s %*%*[^*]",str) == 1) || sscanf(buf,""%*[-]%[^-]s",str) == 1)
if (sscanf(buf,"%*[-]%s %*%*[^-]",str) == 1) || sscanf(buf,""%*[-]%[^-]s",str) == 1)

とやってみたのですが、どちらか一方の形式のものがとれません。
どこが悪いのでしょうか。
両方のかたちから取り出せるよい方法を教えて下さい。


No.5326

Re:sscanfを使って文字列の抽出(もう少し教えて下さい)
投稿者---麗(2003/02/21 16:56:51)


sscanf(buf, "%*[-]%[^- ]s", save);
でどうでしょう?

No.5327

フォロー
投稿者---麗(2003/02/21 17:22:12)


>sscanf(buf, "%*[-]%[^- ]s", save);

%[^- ]の"^-"の後ろに半角スペースがあります。
最初の投稿とはそこ(半角スペースのあること)が違います。

[^-]
[^- ]
…同じに見える?

No.5328

ありがとうございます。
投稿者---つよし(2003/02/21 17:39:51)


>sscanf(buf, "%*[-]%[^- ]s", save);
>でどうでしょう?

ありがとうございます。
上手くいきました。


No.5322

sscanfのついていなので便乗で
投稿者---一歩ずつ(2003/02/21 13:05:36)


sscanfのついていなので便乗で質問させていただきます。

ファイルの中に、
---- 20030221 start ----

---- AAA start ----

---- BBB start ----

とあった場合、最初の「---- 20030221」から始まる数字が含まれている行は、
パスし、それ以降の「----」から始まる行の「AAA」とか「BBB」を取り出した
いのですがsscanfを使用すれば上手くできるのでしょうか。

sscanf(buf,"---- %*[^0-9] ",work);
sscanf(buf,"---- %*[^0123456789] ",work);

とかしてみたのですがダメでした。
それとも読み込んだあと、先頭1バイトが数字かどうか比較した
方がいいのでしょうか。


No.5325

Re:sscanfを使って文字列の抽出
投稿者---通りすがりのインフルエンザ(2003/02/21 14:43:19)


>とあった場合、最初の「---- 20030221」から始まる数字が含まれている行は、
>パスし、それ以降の「----」から始まる行の「AAA」とか「BBB」を取り出した
>いのですがsscanfを使用すれば上手くできるのでしょうか。

>「----AAA xxxx xxxx----」(xxxxには任意の文字が入ります。)
>のかたちだと、「AAA xxxx xxxx」となってしまいます。


sscanf(buf, "----%*[ \t]%[a-zA-Z]", str);

でどうでしょう。
数字の場合は失敗します。ただし、
AA156の場合はAAしか取れません。

No.5330

上手くいったのですが。
投稿者---一歩ずつ(2003/02/21 18:20:56)


ありがとうございます。

>num = sscanf(buf, "----%*[ \t]%[a-zA-Z]", str);
で出来ました。
確かに、レスされているとおりAA156の場合は、AAしか取れませんでした。

sscanf(buf, "----%*[ \t]%[^0-9]", work);
でもできました。

ただ、
「---- 20030221 start ----」のかたちは、パスしましたが、
「---- AAA xxxx ----」、「---- BBB xxxx ----」のかたちでは、
本来ならAAAとかBBBのみを取り出したかったのですが、すべて
でてきました。
数字含みのも取れませんでした。

sscanf(buf, "----%*[ \t]%[^0-9]s %*[^*]", work);
sscanf(buf, "----%*[ \t]%[^0-9][0-9]s %*[^*]", work);
とかしてみたのですがダメでした。

sscanfでやることに無理があるのでしょうか。
取得した後、別方法でした方がいいのでしょうか。


No.5331

Re:上手くいったのですが。
投稿者---インフルエンザ(2003/02/21 18:58:34)


>確かに、レスされているとおりAA156の場合は、AAしか取れませんでした。
AA156のような場合もあるということですか?

sscanf(buf, "----%*[ \t]%1[a-zA-Z]%[a-zA-Z0-9]%*[- \t]", str, str + 1)

ちょっと危険な香りがします・・・。


No.5332

Re:上手くいったのですが。
投稿者---麗(2003/02/21 19:08:43)


横レスで失礼します。
scansetの利用をあきらめてstrcmpを利用するのはどうでしょう?

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

main(int argc, char *argv[])
{
  char buf[BUFSIZ];
  char save[9];

  while(NULL != fgets(buf, sizeof(buf), stdin)){
    sscanf(buf, "%*[- ]%8[^- ]s", save);
    if(strcmp(argv[1], save))       // コマンド引数に"20030221"を指定していれば…
      puts(save);                   // 文字列(AAAとかBBBとか)を出力する。

    else                            // コマンド引数に"20030221"を指定していれば…
      puts("");                     // 何も出力しない。(改行は出力するけど)
  }
  return(0);
}


No.5335

ありがとうございます。
投稿者---一歩ずつ(2003/02/22 09:38:16)


お礼が遅くなりまして。
回答ありがとうございます。また、アドバイスありがとうございます。

sscanfで処理ができれば、簡単でステップ数も少なくてすむと思って
いたのですが、sscanfでやるのには少し無理みたいです。

麗さんのレスにもあるように、あるところまでをsscanfで読み込んで、
文字列比較等でするのがよいかもしれません。