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

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

 詳しくはこちら


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

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


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

No.21271

sscanfを使って必要なデータの取り出し
投稿者---さい(2005/06/08 16:06:12)


ファイルから読み込んだデータからsscanfを使って必要なデータを
取り出しています。

2005/05/20 13:00:23 GMT+09:00 [1234] cmd: mail sender:<taro.yamada@test.co.jp> size=50509\r\n

上記にあるデータから、年、月、日とsender以降の「<>」で囲まれた
文字列と、size=以降の値
2005
05
20
taro.yamada@test.co.jp
50509
を取り出そうとしています。

下記の様なsscanfの使い方にしてみたのですが、年、月、日しか取得
されません。
"sender"以降の「<>」で囲まれた文字列と、"size="以降の値をとる
ことができません。
また、"sender"や"size="が存在しない場合も、処理が実行されて
しまいます。

n=sscanf(buff,"%4s%*c%2s%*c%2s cmd: mail sender:<%s> size=%ld",year,month,day,sender,&size) ;

n=sscanf(buff,"%4s%*c%2s%*c%2s cmd: mail  sender:[^<]<%s[^>]> size=%ld",year,month,day,sender,&size) ;

n=sscanf(buff,"%4s%*c%2s%*c%2s %*%*cmd: mail sender:<%s> size=%ld",year,month,day,sender,&size) ;

n=sscanf(buff,"%4s%*c%2s%*c%2s cmd:%*mail%* sender:<%s> size=%ld",year,month,day,sender,&size) ;

if (n == 5) {
    printf("[%s][%s][%s][%s][%ld]\n",year,month,day,sender,size) ;
}


という具合にやってみたのですがどれも上手くいきません。
上手くいく方法を教えて下さい


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:sscanfを使って必要なデータの取り出し 21274 si 2005/06/08 19:04:27
<子記事> Re:sscanfを使って必要なデータの取り出し 21275 まきじ 2005/06/08 19:04:43


No.21274

Re:sscanfを使って必要なデータの取り出し
投稿者---si(2005/06/08 19:04:27)


n = sscanf(buff,"%4s%*c%2s%*c%2s%*[^<]%*c%[^>]%*[^=]%*c%d",y,m,d,sender,&size);

一寸、これを試してみて下さい。
私が確認したところでは、読み込めますが、返値がおかしいので? ですが。


この投稿にコメントする

削除パスワード

No.21281

Re:sscanfを使って必要なデータの取り出し
投稿者---さい(2005/06/08 20:07:43)



>n = sscanf(buff,"%4s%*c%2s%*c%2s%*[^<]%*c%[^>]%*[^=]%*c%d",y,m,d,sender,&size);
>
>一寸、これを試してみて下さい。
>私が確認したところでは、読み込めますが、返値がおかしいので? ですが。
試してみました。
一応、取得することができました。
ただ、下記に記述したデータの形式に合致するところでは、読み込みが行われ、必要
でない値が返却されます。
例えば、「<>」が含まれているところとか
2005/05/20 13:00:23 GMT+09:00 [1234] xxxx xxxxx xxx(xxxx) <10>ms

すみません。説明が足りませんでした。

参照するデータは、下記の2種類です。
どういわけか、最後に必ず、"\r\n"の4文字が含まれています。
2005/05/20 13:00:23 GMT+09:00 [1234] cmd: mail sender:<taro.yamada@test.co.jp> size=50509\r\n
2005/05/20 13:00:23 GMT+09:00 [1234] cmd: mail to:<hanako.yamada@test.co.jp>\r\n

1行目は、
年、月、日とsender以降の「<>」で囲まれた文字列と、size=以降の値
2005
05
20
taro.yamada@test.co.jp
50509

2行目は、
年、月、日とto以降の「<>」で囲まれた文字列
2005
05
20
hanako.yamada@test.co.jp

を取り出そうとしています。

n=sscanf(buff,"%4s%*c%2s%*c%2s %*[^]]] clt_cmd: MAIL From:%s SIZE=%ld",year,month,day,sender,&size) ;
としてみたのですが。
<> が原因でうまくいかないみたいです。

<> を取り除こうとすると、size=が取れなかったり、>\r\nが付いて
きたりとなります。

まきじさんが書かれているとおり、分けた方がいいのでしょか。
できれば、sscanfの1回で上手くやりたいのですが。



この投稿にコメントする

削除パスワード

No.21284

Re:sscanfを使って必要なデータの取り出し
投稿者---shu(2005/06/08 20:51:38)


>できれば、sscanfの1回で上手くやりたいのですが。

"%d/%d/%d%*[^<]<%[^>]%*[^=]=%ld"

でうまく動きましたよ。


この投稿にコメントする

削除パスワード

No.21290

書式にもう少し条件をつけたいのですが
投稿者---さい(2005/06/08 23:34:54)


>"%d/%d/%d%*[^<]<%[^>]%*[^=]=%ld"
>n = sscanf(buff, "%4s/%2s/%2s%*[^<]<%[^>]%*[^=]=%ld", year, month, day, sender, &size);

ありがとうございます。
試せる環境がないので明日、試して見ます。

ところで、条件をもう少し色を付けたいのですが、
2005/05/20 13:00:23 GMT+09:00 [1234] FC-1245-AD-3312 FC-XXXX-99AD cmd(あいうえお) <10>ms
<>が存在すると引っかかってきます。
「cmd: mail sender」とか「size」を付けて強くしたいのですが。

2005/05/20 13:00:23 GMT+09:00 [1234] cmd: mail to:<hanako.yamada@test.co.jp>\r\n
の場合ですが、
%*[^<]<%[^>]%*[^=]=%ld"
を直せば、年、月、日、to以降の<>で囲まれた文字列を読めますか。



この投稿にコメントする

削除パスワード

No.21291

Re:書式にもう少し条件をつけたいのですが
投稿者---elder(2005/06/09 01:39:42)


>2005/05/20 13:00:23 GMT+09:00 [1234] FC-1245-AD-3312 FC-XXXX-99AD cmd(あいうえお) <10>ms
><>が存在すると引っかかってきます。
>「cmd: mail sender」とか「size」を付けて強くしたいのですが。

付ける?強くするとは??


>2005/05/20 13:00:23 GMT+09:00 [1234] cmd: mail to:<hanako.yamada@test.co.jp>\r\n
>の場合ですが、
>%*[^<]<%[^>]%*[^=]=%ld"
>を直せば、年、月、日、to以降の<>で囲まれた文字列を読めますか。

読めますよ。
"%4s/%2s/%2s%*[^<]<%[^>]"


この投稿にコメントする

削除パスワード

No.21295

Re:書式にもう少し条件をつけたいのですが
投稿者---さい(2005/06/09 10:15:42)


>>2005/05/20 13:00:23 GMT+09:00 [1234] FC-1245-AD-3312 FC-XXXX-99AD cmd(あいうえお) <10>ms
>><>が存在すると引っかかってきます。
>>「cmd: mail sender」とか「size」を付けて強くしたいのですが。
>
>付ける?強くするとは??

すみません。意味不明な質問しまして。

sscanfの書式に「cmd: mail sender」とか「size」とかを盛り込んで、
正確にしたいとうか、読み込みの性能を上げたいのです。
sscanfの戻り値で、正しく取得できたか判断できますが、戻り値が同じ
な場合が発生します。
その場合は、sscanfでの読み込みは正常と判断できても、読み込んだ値
が期待したものか判断できないので、sscanfの書式に付けたかったのです。



この投稿にコメントする

削除パスワード

No.21294

Re:書式にもう少し条件をつけたいのですが
投稿者---かずま(2005/06/09 02:56:27)


#include <stdio.h>

char *data[] = {
  "2005/05/20 13:00:23 GMT+09:00 [1234] cmd: mail sender:<taro.yamada@test.co.jp> size=50509\r\n",
  "2005/05/20 13:00:23 GMT+09:00 [1234] cmd: mail to:<hanako.yamada@test.co.jp>\r\n",
  "2005/05/20 13:00:23 GMT+09:00 [1234] FC-1245-AD-3312 FC-XXXX-99AD cmd(あいうえお) <10>ms\r\n",
};

void proc(const char *data)
{
    char year[5], month[3], day[3], sender[256];  long size;  int n;

    n = sscanf(data, "%4s/%2s/%2s%*[^]]] cmd: mail%*[^<]<%255[^>]> size=%ld",
        year, month, day, sender, &size);
    if (n == 5)
        printf("sender: [%s][%s][%s][%s][%ld]\n", year, month, day, sender, size);
    else if (n == 4)
        printf("to:     [%s][%s][%s][%s]\n", year, month, day, sender);
    else
        printf("bad data: %.64s ...\n", data);
}

int main(void)
{
    int i;
    for (i = 0; i < 3; i++) proc(data[i]);
    return 0;
}



この投稿にコメントする

削除パスワード

No.21297

Re:書式にもう少し条件をつけたいのですが
投稿者---さい(2005/06/09 11:17:01)


ありがとうございます。
参考になります。


この投稿にコメントする

削除パスワード

No.21285

Re:sscanfを使って必要なデータの取り出し
投稿者---elder(2005/06/08 21:04:26)


n = sscanf(buff, "%4s/%2s/%2s%*[^<]<%[^>]%*[^=]=%ld", year, month, day, sender, &size);

これでどうでしょうか?


この投稿にコメントする

削除パスワード

No.21287

向学&無理には。
投稿者---れつ(2005/06/08 23:14:27)


sscanfを使ったことがないので何ともいえませんが、あるとことで妥協するのも
1つかと思います。

無理であるのならば、きれいな形でとれるところまで取ってその後、編集をする
とか。

ところで、以下のsscanfの書式教えて下さい。

向学ですが、
「%*[^<]%*c%[^>]%*[^=]%*c%d」のところが分からないのですが、

"[^"という記述は、[]内部に指定した文字種類以外を読み飛ばしますが、
"[^<]<"と書くのではないのでしょうか。
「%*[^<]%*c%[^>]%*[^=]%*c%d」となるのでしょうか。
この書式の意味を教えて下さい。




この投稿にコメントする

削除パスワード

No.21289

Re:向学&無理には。
投稿者---まきじ(2005/06/08 23:34:16)


>"[^<]<"と書くのではないのでしょうか。
>「%*[^<]%*c%[^>]%*[^=]%*c%d」となるのでしょうか。

%*[^<] で < まで読み飛ばし、< も読み飛ばしたいので
%*c として、< の一文字読み飛ばします。

%*[^=]%*c の部分も同じです。


この投稿にコメントする

削除パスワード

No.21275

Re:sscanfを使って必要なデータの取り出し
投稿者---まきじ(2005/06/08 19:04:43)


<> が原因でうまくいかないみたいです(^^;

strchr を使って、こんな感じです。

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

int main(void){

    char buf[]="2005/05/20 13:00:23 GMT+09:00 [1234] cmd: mail sender:<taro.yamada@test.co.jp> size=50509 ";
    
    int year, month, day;
    char *p, sender[64]={'\0'};
    long size;
    
    sscanf(buf,"%d/%d/%d %*s GMT+09:00 [1234] cmd: mail sender:%s size=%ld",&year,&month,&day,sender,&size);
    
    p = strchr(sender,'>');
    if(p) *p = '\0';
    
    sprintf(buf,"%d/%d/%d %s %ld\n",year,month,day,sender+1,size);
    
    printf("%s",buf);
}



この投稿にコメントする

削除パスワード

No.21286

向学&無理には
投稿者---れつ(2005/06/08 23:03:27)


sscanfを使ったことがないので何ともいえませんが、あるとことで妥協するのも
1つかと思います。

無理であるのならば、きれいな形でとれるところまで取ってその後、編集をする
とか。

ところで、以下のsscanfの書式教えて下さい。

向学ですが、
「%*[^<]%*c%[^>]%*[^=]%*c%d」のところが分からないのですが、

"[^"という記述は、[]内部に指定した文字種類以外を読み飛ばしますが、
"[^<]<"と書くのではないのでしょうか。
「%*[^<]%*c%[^>]%*[^=]%*c%d」となるのでしょうか。
この書式の意味を教えて下さい。



この投稿にコメントする

削除パスワード

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