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

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

 詳しくはこちら


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

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


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

No.21593

ファイルからの読み込み
投稿者---のむら(2005/06/24 01:34:51)


データの取り出し方法を教えてください。

以下の様なブロックのデータがあります。
ブロックは、”nm=”から始まり、改行コードまでが1ブロックです。
1ブロックは、”nm=”が2つあり、"text"は、では改行コードがあります。
"nm="の項目と”s=”の項目と"g=”の項目を取り出してファイルに
出力しようとしています。
”nm="の行は2行あるので、先頭の”nm="を対象とし、”ou=”があるかない
かで判断します。ただ、先頭の”nm=”に”ou=”が含まれない場合もあり、その
ときは、エラーして1行をエラーのファイルに出力。

1行ずつファイルから読み込み、必要な項目を変数に格納して、ブロックの終わり
が来たらファイルに出力と考えていたのですが、

1案
改行コードがブロックの終わりなので、0x0a 来たらファイルに出力しようと
したのですが、"text="の項目にも、改行コードがあるためブロックの終わり
でないの終了と判断してしまためうまくいかない。

2案
改行コードの”0x0a”で判断せず、”nm=”行に”ou=”が含まれていたら次の
ブロックということで、前に読み込んだブロックをファイルに出力。
しかし、そうすると一番最初にあるブロックが出力できないのと、”ou=”が
存在しない場合、エラーとしてファイルに出力できない。

つきましては、考え方を教えてください。
どのような流れ、動きにしたらよいのでしょうか、教えてください。

--ここから------------------
nm=aaaa.bbb,ou=tv,o=123,o=co
u=1111
sub=bbbb
text=あああああ
nm=aaaa.bbb
s=aaaa
g=bbbb
o=gggg
id=2222
pw=3333

nm=aaaa.bbb,ou=tv,o=123,o=co
u=1111
sub=bbbb
text=あああああ


いいいい
nm=aaaa.bbb
s=aaaa
g=bbbb
o=gggg
id=2222
pw=3333

nm=aaaa.bbb,ou=tv,o=123,o=co
u=1111
sub=bbbb
text=あああああ
nm=aaaa.bbb
s=aaaa
g=bbbb
o=gggg
id=2222
pw=3333

nm=aaaa.bbb,o=123,o=co
u=1111
sub=bbbb
text=あああああ
nm=aaaa.bbb
s=aaaa
g=bbbb
o=gggg
id=2222
pw=3333


--ここまで---------------


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:ファイルからの読み込み 21594 RAPT 2005/06/24 01:56:27
<子記事> Re:ファイルからの読み込み 21600 かずま 2005/06/24 09:52:10


No.21594

Re:ファイルからの読み込み
投稿者---RAPT(2005/06/24 01:56:27)


開発環境は?

> ブロックは、”nm=”から始まり、改行コードまでが1ブロックです。
> 1ブロックは、”nm=”が2つあり、"text"は、では改行コードがあります。

??? 定義がなんかおかしい。
ん?もしかして、
「ブロックは、”nm=”から始まり、改行コードのみの行(=空行)までが1ブロックです。」
ってこと?
にしても2行目が意味不明。


改行区切り、1行ずつ処理なら、fgets()が使えると思います。
fgets()は改行文字かファイルの終端までを読みます。
1行読んだら sscanf() で解析すればよいかと。

char var_name[10], var_val[100], buff[BUFSIZ];
fgets(fp, buff, sizeof(buff));
sscanf(buff, " %[^=]=%s", var_name, var_value);

// nm=の行で ,ou= が見つからない場合はエラー、の例
if( strcmp(var_name, "nm") == 0 && strstr(var_value, ",ou=") == NULL ){
    // error
}




この投稿にコメントする

削除パスワード

No.21595

Re:ファイルからの読み込み
投稿者---のむら(2005/06/24 02:16:35)


>開発環境は?
>
>> ブロックは、”nm=”から始まり、改行コードまでが1ブロックです。
>> 1ブロックは、”nm=”が2つあり、"text"は、では改行コードがあります。
>
>??? 定義がなんかおかしい。
>ん?もしかして、
>「ブロックは、”nm=”から始まり、改行コードのみの行(=空行)までが1ブロックです。」
>ってこと?
>にしても2行目が意味不明。

環境は、
OSが、Solaris8
コンパイルが、gcc

>「ブロックは、”nm=”から始まり、改行コードのみの行(=空行)までが1ブロックです。」ってこと?
その通りです。
ブロックの中に再度、”nm=”がでてくる(存在する)のです。
また、”text=”は、1行ではなく、改行コードのみの行(=空行)を交えて、何行からなります。

そのため、
最初は、改行コードでブロックの終わりと判断したのですが、行きませんでた。
”nm=”がブロックの開始だから、”nm=”がでてきたら終わったと判断しようとしたのですが、
ブロック内で、再度ででくるので、”nm=”行内で必ずでてくるキーワードで判断しようとしました。
しかし、そうすると一番最初にあるブロックが出力できないのと、”ou=”が
存在しない場合、エラーとしてファイルに出力できない。

ブロックが終わって次ぎのブロックがきたとき前回読み込んだんだブロックの内容をファイルに出力させる
判断がうまくできないので教えて下さい。


この投稿にコメントする

削除パスワード

No.21596

Re:ファイルからの読み込み(追加)
投稿者---のむら(2005/06/24 02:38:34)


”nm=”から始まる行は、ブロック内に再度でてきます。
再度、でてきた婆愛は、そのままパスしたいのです。
”ou=”が内からエラーとか、ブロックが終わったから
前ブロックの内容をファイルに出力とかしたくないのです。



この投稿にコメントする

削除パスワード

No.21597

Re:ファイルからの読み込み(追加)
投稿者---あかま(2005/06/24 02:58:22)


>ブロックが終わって次ぎのブロックがきたとき前回読み込んだんだブロックの内容をファイルに出力させる判断がうまくできないので教えて下さい。
>”nm=”から始まる行は、ブロック内に再度でてきます。再度、でてきた婆愛は、そのままパスしたいのです。
>”ou=”が内からエラーとか、ブロックが終わったから前ブロックの内容をファイルに出力とかしたくないのです。

次々、条件が出てくるとよくわからなくなるのですが、結局のところなにがしたいので?

>最初は、改行コードでブロックの終わりと判断したのですが、行きませんでた。
↓のプログラムではだめですか?
空行が2連続であるとそこで読み込み終了しちゃいますが。

#include <stdio.h>

int read_block(char block[][128],FILE *fp){//1ブロック読み込み
    int i;
    for(i=0;i < 20;i++){
        if(fgets(block[i],128,fp) == NULL || block[i][0] == '\n') break;//読み込み終了か'\n'だけの行なら抜ける
    }
    return i;
}

int main(){
    char block[20][128];
    FILE *fp;
    int i,j;
    
    fp = fopen("read.txt","r");
    
    while(i = read_block(block,fp)){
        printf("******block******\n");
        for(j=0;j < i;j++){//読み込んだブロックの出力
            printf("%s",block[j]);
        }
    }
    return 0;
}




この投稿にコメントする

削除パスワード

No.21598

Re:ファイルからの読み込み
投稿者---ぽへぇ(2005/06/24 05:24:57)


pwの行を読んだら終わりってのは、だめですかねぇ。

要素数と順番が決まっている、と期待して良いのなら
そのとおりに読んでみては。



この投稿にコメントする

削除パスワード

No.21600

Re:ファイルからの読み込み
投稿者---かずま(2005/06/24 09:52:10)


> つきましては、考え方を教えてください。
> どのような流れ、動きにしたらよいのでしょうか、教えてください。
> 
> --ここから------------------
> nm=aaaa.bbb,ou=tv,o=123,o=co
> u=1111

> id=2222
> pw=3333
> 
> 
> --ここまで---------------

その入力の場合の出力例を示してください。



この投稿にコメントする

削除パスワード

No.21601

Re:ファイルからの読み込み
投稿者---のむら(2005/06/24 11:26:49)


1.ファイルから1行ずつ読み込みます。
2.行の先頭が”nm=”の場合、それ以降を変数に格納。
3.行の先頭が”s=”の場合、それ以降を変数に格納。
4.行の先頭が”g=”の場合、それ以降を変数に格納。
5.1ブロックの終了が来たら、変数に格納した値をファイルに出力。

ブロックは、”nm=”から始まり、改行コードのみの行(=空行)までが1ブロックです。
 1ブロックの終了を、改行コードのみの行で判断するのではなく、ブロックの始まり”nm=”の行
 で判断し、出力処理を行います。
 行の先頭が”text=”では、改行コードのみの行を含む複数行からなるからです。

> --ここから------------------
>nm=aaaa.bbb,ou=tv,o=123,o=co
>u=1111
>sub=bbbb
>text=あああああ


>いいいい
>nm=aaaa.bbb
>s=aaaa
>g=bbbb
>o=gggg
>id=2222
>pw=3333

> --ここまで---------------

aaaa.bbb,ou=tv,o=123,o=co
aaaa
bbbb
を出力します


この投稿にコメントする

削除パスワード

No.21618

Re:ファイルからの読み込み
投稿者---かずま(2005/06/24 19:35:21)


4つのブロックがあるのに、結果が 1つでは、エラーをどう出力していいのか分かりません。
また、text= の終了が何かも定義されていないので、= があるところまでとしてみました。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct { char *nm, *s, *g; } Block;

int read_block(Block *block, FILE *fp)
{
    char buf[256], *p = NULL;  int n;

    free(block->nm), free(block->s), free(block->g);
    while (fgets(buf, sizeof buf, fp)
            && (memcmp(buf, "nm=", 3) || !strstr(buf, ",ou=")))
        if (buf[0] != '\n') printf("error: %s", buf);
    block->nm = strdup(buf+3);
    for (n = 0; p || fgets(buf, sizeof buf, fp) && buf[0] != '\n'; n++) {
        p = 0;
        if (!memcmp(buf, "s=", 2)) block->s = strdup(buf+2);
        else if (!memcmp(buf, "g=", 2)) block->g = strdup(buf+2);
        else if (!memcmp(buf, "text=", 5))
            while (fgets(buf, sizeof buf, fp) && !(p = strchr(buf, '='))) ;
    }
    return n;
}

int main(void)
{
    Block block = { 0 };

    while (read_block(&block, stdin))
        printf("%s%s%s\n", block.nm, block.s, block.g);
    return 0;
}



この投稿にコメントする

削除パスワード

No.21622

Re:ファイルからの読み込み
投稿者---のむら(2005/06/24 23:57:58)


すみません。

私が言っているブロックとは、
”nm=aaaa.bbb,ou=tv,o=123,o=co”ら始まり、改行コードのみの行(=空行)までを
1ブロックとしています。
”nm=aaaa.bbb,ou=tv,o=123,o=co”はあくまでも1行です。

”nm=aaaa.bbb,ou=tv,o=123,o=co”では、ou=が存在するので、を変数に格納します。
仮に、
”nm=aaaa.bbb,o=123,o=co”の場合は、ou=が存在しないので、読み込んだレコードを
”nm=aaaa.bbb,o=123,o=co”をログに出力します。

次に、再度、”nm=aaaa.bbb”がでてきますが、この場合は無視します。
後は、
行の先頭が”s=”の場合、それ以降を変数に格納
行の先頭が”g=”の場合、それ以降を変数に格納

text= の終了が何かも定義されていないので、次の= があるところまでとなります。


この投稿にコメントする

削除パスワード

No.21623

Re:ファイルからの読み込み
投稿者---dark(2005/06/25 00:03:57)


ていうか、仕様どおりつくってもらいたいのですか?
近かれ遠かれ、ヒントにはなるとおもいますが?

自分のやりたいとおりに一度プログラムを書いてください。
ここはサポートセンターじゃありません。


この投稿にコメントする

削除パスワード

No.21635

Re:ファイルからの読み込み
投稿者---かずま(2005/06/25 04:23:24)


>   while (fgets(buf, sizeof buf, fp)
>           && (memcmp(buf, "nm=", 3) || !strstr(buf, ",ou=")))
>       if (buf[0] != '\n') printf("error: %s", buf);

これを次のように訂正します。

    for (;;) {
        if (!fgets(buf, sizeof buf, fp)) return 0;
        if (!memcmp(buf, "nm=", 3) && strstr(buf, ",ou=")) break;
        if (buf[0] != '\n') printf("error: %s", buf);
    }



この投稿にコメントする

削除パスワード

No.21638

Re:ファイルからの読み込み
投稿者---shu(2005/06/25 11:22:11)


000: /*
001:     ファイル入出力プログラム
002:     
003:     読みこみファイルは、コマンドライン引数から。
004: */
005: 
006: #include <stdio.h>
007: #include <stdlib.h>
008: #include <string.h>
009: 
010: #define F_NAME  (argv[1])
011: 
012: int main( int argc, char *argv[] )
013: {
014:     FILE *fp = NULL;
015:     char buf[BUFSIZ] = "";
016:     
017:     if (argc != 2
018:         || (fp = fopen( F_NAME, "r" )) == NULL)
019:         exit( 1 );
020:         
021:     while(fgets( buf, sizeof buf, fp ))
022:     {
023:         // nm= 1回目
024:         if (!strncmp( buf, "nm=", 3 ))
025:             puts( strtok( buf, ",\n" ) );
026:         
027:         // nm= 2回目
028:         else if (!strncmp( buf, "text=", 5 ))
029:             while (strncmp( buf, "nm=", 3 ))
030:                 fgets( buf, sizeof buf, fp );
031:         
032:         // s=, g=
033:         else if (!strncmp( buf, "s=", 2 )
034:             || !strncmp( buf, "g=", 2 ))
035:             fputs( buf, stdout );
036:         
037:         // pw= ブロック区切り
038:         else if (!strncmp( buf, "pw=", 3 ))
039:             fputs( ";\n", stdout );
040:     }
041:     
042:     fclose( fp );
043:     
044:     return 0;
045: }
046: /*** by shu ***/


こんな感じはどうかな?


この投稿にコメントする

削除パスワード

No.21642

Re:ファイルからの読み込み
投稿者---のむら(2005/06/25 14:17:53)


下手な説明で分かりづらくて申し訳ありませんでした。
かずまさん、shuさん、みなさん、アドバイスありがとございます。

"nm=”から始まっている行は、2行ありますが、最初のみを
参照します。
”nm=aaaa.bbb,ou=tv,o=123,o=co”では、ou=が存在するので、
"nm="以降を変数に格納します。
仮に、
”nm=aaaa.bbb,o=123,o=co”の場合は、ou=が存在しないので、
読み込んだレコードを”nm=aaaa.bbb,o=123,o=co”をログに
出力します。

並びもきまっていないのですが、必ず、”nm=”が一番最小に
きます。

”nm=”ひとつとっても色々とありますが、アドバイスを参考
に作ってみます。



この投稿にコメントする

削除パスワード

No.21669

Re:ファイルからの読み込み
投稿者---ぽへぇ(2005/06/27 01:07:08)


textが終わりかどうかはどうやって判断するの?
それがわかればブロックの終わりも判断できるかもね。



この投稿にコメントする

削除パスワード

No.21680

Re:ファイルからの読み込み
投稿者---のむら(2005/06/27 21:46:48)


>textが終わりかどうかはどうやって判断するの?
>それがわかればブロックの終わりも判断できるかもね。

難しいです。
次の”=”がでてくるまでや、”???=”で判断しても、
textに中に含まれていたらアウトです。



この投稿にコメントする

削除パスワード

No.21681

Re:ファイルからの読み込み
投稿者---shu(2005/06/27 23:11:36)


>次の”=”がでてくるまでや、”???=”で判断しても、
>textに中に含まれていたらアウトです。

読む込む前に、データとしてアウトだと思います。
データとしてアウトなので、読みこまなくても良いはず。
どちらかといえば、データを作るプログラムの問題かと思います。

text= から nm= の「行頭」に、
例えば、s= や g= などを設定した場合、
データを作成するプログラムは、どういった出力をするでしょうか?

何らかのデータの改変があると思うのですが?


この投稿にコメントする

削除パスワード

No.21687

Re:ファイルからの読み込み
投稿者---ぽへぇ(2005/06/28 18:38:36)


ごめん。上の方に書いてあった。

No.21622
>text= の終了が何かも定義されていないので、次の= があるところまでとなります。

一方、
No.21680
>次の”=”がでてくるまでや、”???=”で判断しても、
>textに中に含まれていたらアウトです。

って、データの形式に問題があるって気付いているじゃん ^^;
あとはshuさんの指摘どおり、そういった特殊な状態でデータが
どう変化するかを観察してルールを見つける。

課題か何かだったら、出題者に聞いてみては?



この投稿にコメントする

削除パスワード

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