C言語関係掲示板

過去ログ

No.502.ファイルから読み込んだレコードのカウント

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

ファイルから読み込んだレコードのカウント
投稿者---よしみ(2002/12/11 01:51:26)


以下のように、改行でくぎられているデータのブロックから「originator」と
「recipient-to」または、「「recipient-cc」をとりだし、「originator」
の行に含まれるコードに対する「recipient-to」または、「「recipient-cc」の数を数え、最終的に、コード毎のその合計を求めたいのです。
ただし、「originator」、「recipient-to」、「recipient-CC」に「+DIRSYNC」があった場合は除きます。

routing
type 0 message
time 1039445992 Mon Dec 9 23:59:52 2002 +540
ua-message-id H00014ef2775903e.1039445992.SVR-1
mta-message-id H00014ef2775903e.1039445992.SVR-1
originator EIGYO-GRP / SVR-1, EIGYO, MARUNOUCHI
recipient-to Yamada Taro / SVR-2, EIGYO, MARUNOUCHI
ack-req 0 none
recipient-to Yamada Hanako / SVR-2, EIGYO, MARUNOUCHI
ack-req 0 none
recipient-to Yamada Ichitaro / SVR-2, EIGYO, MARUNOUCHI
ack-req 0 none
recipient-to Yamada Yonshiro / SVR-2, EIGYO, MARUNOUCHI
ack-req 0 none
recipient-to Yamamoto Taro / SVR-2, EIGYO, MARUNOUCHI
ack-req 0 none
recipient-to Urutoraman Taro / SVR-12, EIGYO, MARUNOUCHI
ack-req 0 none
message-size 5823
delivered-count 6

routing
time 1039445970 Mon Dec 9 23:59:30 2002 +540
type 0 message
originator +DIRSYNC / SVR-0
ua-message-id H00000004f7c0f25
mta-message-id H00000004f7c0f25
recipient-to +DIRSYNC / SVR-1
ack-req 0 none
queue DIRSYNC
message-size 787
delivered-count 1

routing
time 1039445992 Mon Dec 9 23:59:52 2002 +540
type 0 message
ua-message-id H00014ef2775903e.1039445992.SVR-1
mta-message-id H00014ef2775903e.1039445992.SVR-1
originator EIGYO-ORG / SVR-1, EIGYO, MARUNOUCHI
recipient-to Urutoraman Syodai / SVR-2, EIGYO, MARUNOUCHI
ack-req 0 none
recipient-to Urutoraman KeTsutekita / SVR-2, EIGYO, MARUNOUCHI
ack-req 0 none
recipient-to Urutoraman Sebun / SVR-3, EIGYO, MARUNOUCHI
ack-req 0 none
message-size 5823
delivered-count 2

routing
time 1039445949 Mon Dec 9 23:59:09 2002 +540
type 0 message
originator Iwaki Hatsupa / SVR-1, KIKAKU, OOTEMACHI
ua-message-id H000021c0293476e.1039445841.AME-0A
mta-message-id H000021c0293476e.1039445841.AME-0A
recipient-to Tokugawa Nonbe / SVR-1, EIGYO, MARUNOUCHI
ack-req 0 none
queue LOCAL
message-size 1262
delivered-count 1

routing
time 1039446006 Tue Dec 10 00:00:06 2002 +540
type 0 message
originator CHK-1 / SVR-3
ua-message-id H00002670e550664.1039446033.SVR-3.mailbox.co.jp
mta-message-id H00002670e550664.1039446033.SVR-3.mailbox.co.jp
recipient-to Check Status / SVR-1, TOKXQ, MARUNOUCHI
ack-req 0 none
queue LOCAL
message-size 1157
delivered-count 1


結果として、
コード=EIGYO 回数=8
コード=KIKAKU 回数=1
コード=CHK-1 回数=1

お願いします。

No.3800

Re:ファイルから読み込んだレコードのカウント
投稿者---かずま(2002/12/11 03:15:15)


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

int main(void)
{
    char buf[1024], code[1024];
    struct { char *code; int count; } table[100];
    int i = 0, n = 1;

    table[0].code = "+DIRSYNC";
    while (fgets(buf, sizeof buf, stdin))
        if (memcmp(buf, "originator ", 10) == 0) {
            if (sscanf(buf+10, "%*[^,], %[^,]", code) == 1 ||
                    sscanf(buf+10, "%s", code) == 1) {
                for (i = 0; i < n && strcmp(code, table[i].code); i++)
                    ;
                if (i == n) {
                    n++;
                    table[i].code = strdup(code);
                    table[i].count = 0;
                }
            }
        } else if (memcmp(buf, "recipient-", 10) == 0)
            table[i].count++;
    for (i = 1; i < n; i++)
        printf("コード=%s  回数=%d\n", table[i].code, table[i].count);
    return 0;
}

結果が次のようになるんですが、EIGYO が 8回にならないといけないのでしょうか。

コード=EIGYO  回数=9
コード=KIKAKU  回数=1
コード=CHK-1  回数=1


No.3804

Re:ファイルから読み込んだレコードのカウント
投稿者---よしみ(2002/12/11 12:17:13)


>結果が次のようになるんですが、EIGYO が 8回にならないといけないのでしょうか。

申し訳ありません、EIGYOの求めている回数が間違っていました。
9回です。

ありがとうございました。
とてもたすかりました。



No.3846

ソース中の構造体の宣言、使い方について
投稿者---あたる(2002/12/13 16:53:50)


>struct { char *code; int count; } table[100];
は、構造体定義をしていると思うのですが、
このような書き方をしてもよいのですか。?

本来なら、
typedef struct {
char *code ;
int count ;
} TABLE ;
struct TABLE table ;
とか
struct TABLE {
char *code ;
int count ;
} ;
struct TABLE table ;
と書くじゃないですか。
どう違うのですか。

No.3851

Re:ソース中の構造体の宣言、使い方について
投稿者---かずま(2002/12/13 19:55:34)


>> struct { char *code; int count; } table[100];
> は、構造体定義をしていると思うのですが、
> このような書き方をしてもよいのですか。?

よいのです。エラーや警告を出すコンパイラがありますか?
(1) struct { char *code; int count; } table[100];

(2) typedef struct { char *code; int count; } TABLE;
    TABEL table[100];

(3) struct TABLE { char *code; int count; };
    struct TABLE table[100];

(1) は、無名構造体を宣言し、同時に変数名 table を宣言している。

(2) は、無名構造体を宣言し、同時に typedef名 TABLE を宣言している。
さらに、その typedef名 TABLE を使って、変数名 table を宣言している。

(3) は、構造体のタグ名 TABLE を宣言し、同時に構造体を宣言している。
さらに、その タグ名 TABLE を使って、変数名 table を宣言している。

(1)は、無名構造体のため、他の場所でこの構造体の変数を宣言できないこと
が、(2)や(3)との大きな違いです。

No.3809

向学 sscanfの使い方
投稿者---said(2002/12/11 17:28:09)


if (sscanf(buf+10, "%*[^,], %[^,]", code) == 1 ||
sscanf(buf+10, "%s", code) == 1) {
の判定分で、
sscanfを使って、"originator "の行のcodeを取得していると
思うのですが、「"%*[^,], %[^,]", 」の意味、使い方を教えて
下さい。



No.3815

Re:向学 sscanfの使い方
投稿者---かずま(2002/12/12 02:11:11)


> sscanfを使って、"originator "の行のcodeを取得していると思うのですが、
> 「"%*[^,], %[^,]", 」の意味、使い方を教えて下さい。
"%*[^,]"   「,」以外の文字が続く限り、それを読み飛ばす。
","        「,」を読み飛ばす。
" "         0個以上の空白を読み飛ばす。
"%[^,]"    「,」以外の文字が続く限り、それを読み込む。

char code[1024];
char buf[1024] = "originator EIGYO-ORG / SVR-1, EIGYO, MARUNOUCHI\n";
のとき、sscanf(buf+10, "%*[^,], %[^,]", code) で、
"EIGYO-ORG / SVR-1" を読み飛ばし、"," を読み飛ばし、" " を読み飛ばし、
"EIGYO" を読み込んで code に入れます。sscanf は読み込んだ項目数 1 を返します。

char buf[1024] = "originator CHK-1 / SVR-3\n"; のときは、
"CHK-1 / SVR-3\n" を読み飛ばし、"," を読み飛ばせないので、sscanf はそこで
終了し、この場合、EOF を返します。


No.3819

参考になります。
投稿者---said(2002/12/12 12:59:05)


ありがとうございます。


No.3847

Re:ファイルから読み込んだレコードのカウント
投稿者---よしみ(2002/12/13 17:38:55)



「originator」の行がないブロックが存在し、
そのため、前のブロックで処理されたコードに
+1加算されてしまいます。
これを防ぐにはどうしらたよいのですか。


No.3852

Re:ファイルから読み込んだレコードのカウント
投稿者---かずま(2002/12/13 19:57:04)


> 「originator」の行がないブロックが存在し、
> そのため、前のブロックで処理されたコードに
> +1加算されてしまいます。
> これを防ぐにはどうしらたよいのですか。

ブロックの定義が書かれていませんが、routing の行がブロックの開始だとすると、
    else if (memcmp(buf, "routing", 7) == 0)
        i = 0;
を追加すればよいのではありませんか。どこに追加するのかは分かるでしょう。

No.3864

Re:ファイルから読み込んだレコードのカウント
投稿者---よしみ(2002/12/14 10:33:27)


ありがとうございます。
上記、判定文を入れると、該当しない場合は、すべて、table[0]に入れて
しまうわけですね。
たしかし、前の処理に加算されなくなりました。