C言語関係掲示板

過去ログ

No779 NUL文字を含むテキストからデータを取り出す

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

sscanfを使用してデータの取り出し
投稿者---やくも(2003/10/09 21:28:16)


ファイルから以下のデータを1レコードずつ読み込み、からsscanfを使って、
該当位置にある値を取り出そうとしているのですが、該当位置がNULL(要は
「,,」となっているところ)だと、それ以降が取り出せません。
sscanfは、NULLがあるとそれ移行は、取り出すことができないのしょうか。
また、数字の部分は、小数点となっており、文字列としてではなく、数値と
して取り出したいのですがどうすればよいのすか。


名と姓とサーバと数値7の内容をsscanfで取り出しています。
取り出す位置に値があると、ちゃんと取り出せますが、
姓が入っていない場合(NULL)の時は、それ以降が取りだせません。
また、数値7を文字としてではなく数値とし取り出したいのですが、
変数を「double」として、sscanfでの呼び出し方法を「%f」とした
のですが、上手く行きません。

sscanf(buff,"%*[^,],%[^,],%[^,],%[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%*[^,],%[^\n]",mei_name,sei_name,svr,size) ;

No,名,姓,サーバ,コード,数値1,数値2,数値3,数値4,数値5,数値6,数値7
1,EIGYO-1,,SVR-01,A0001,18.436,0.002,0.153,404.819,0.013,0.001,423.424
2,Ieyasu,Tokugawa,SVR-01,B0001,7.764,0.002,2.094,319.184,0.001,0.001,329.046
3,EIGYO-2,,SVR-01,B0001,0.044,0.002,0.003,320.65,0.004,0.001,320.704
4,Hideyoshi,Toyotomi,SVR-01,A0001,0.099,0.366,0.001,242.702,0.002,8.588,251.758
5,Kanbei,Kuroda,SVR-01,C0001,86.904,0.002,106.364,7.985,0.001,0.028,201.284
6,Nagamasa,Azai,SVR-01,A0001,18.698,0.001,0.458,122.738,0.005,0.001,141.901
7,Yoshikage,Asakura,SVR-01,C0002,86.811,0.001,51.048,0.029,0.016,0.025,137.93
8,Narimasa,Sasa,SVR-01,B0001,80.57,0.001,37.501,6.059,0.004,0.01,124.145
9,KIKAKU-1,,SVR-01,A0002,2.043,0.002,3.979,112.714,0.002,0.257,118.997
10,Tadateru,Kyogoku,SVR-01,C0003,103.162,1.65,7.771,6.22,0.004,0.096,118.903


No.9682

Re:sscanfを使用してデータの取り出し
投稿者---RAPT(2003/10/09 22:26:59)


>sscanfは、NULLがあるとそれ移行は、取り出すことができないのしょうか。
この辺、詳しくは知らないので…。
strtok()を使ってみるとか。

>また、数字の部分は、小数点となっており、文字列としてではなく、数値と
>して取り出したいのですがどうすればよいのすか。
%dとか%fとか。あとは、一度文字列として取得してから atoiやatof等で
変換するとか。


No.9687

sscanfはNULLを取り出せない?
投稿者---やくも(2003/10/10 01:08:32)


いろいろと探してみたのですが、sscanfではNULLが扱えるのか
分かりませんでした。
scanfがNULL(空リターン)ができなのを考えると扱えなのかも
しれません。

sscnafの戻り値で処理を判断します。


No.9692

Re:sscanfはNULLを取り出せない?
投稿者---やくも(2003/10/10 12:07:23)


strtok()もNULLはとりだせまんでした。

「aaa,,bbb,ccc」
をstrtokで取り出すと「,,」の部分は飛ばして次に逝きます。

strstrで工夫するか、sscanfの戻り値で判断して、条件に
あったsscanfを複数回実行するか。





No.9697

Re:sscanfを使用してデータの取り出し
投稿者---たか(2003/10/10 14:56:44)


>ファイルから以下のデータを1レコードずつ読み込み、からsscanfを使って、
>該当位置にある値を取り出そうとしているのですが、該当位置がNULL(要は
>「,,」となっているところ)だと、それ以降が取り出せません。
>sscanfは、NULLがあるとそれ移行は、取り出すことができないのしょうか。

以下のようにすれば空文字は読み飛ばせます。但し%[]は%sに相当します
ので、空文字の場合代入動作はしません。それに気を付ければ使えると
思います。

#include <stdio.h>

int main(void)
{
int i;
char c;
char a[128], b[128];

i = scanf("%[^,],%[^,],%c", a, b, &c);

printf("%d %s %s %c\n", i, a, b, c);

return 0;
}

No.9703

Re:sscanfを使用してデータの取り出し
投稿者---やくも(2003/10/10 23:04:54)


#include <stdio.h>

int main(void)
{
int i;
char a[128], b[128], c[128],d[128] ;
char buf[128] ;

strncpy(buf,"aaa,bbb,,ddd",13) ;

i = sscanf(buf,"%[^,],%[^,],%s,%[^\n]", a, b, c, d);

printf("%d %s %s %s %s\n", i, a, b, c,d);

return 0;
}

とやったら上手く動いたのですが、「,」が含まれてしまいます。

strncpy(buf,"aaa,bbb,111,ddd",16) ;

とした場合は、4個にならず、3個になります。

やはり、1回でやるのむりなのでしょうか。

No.9704

Re:sscanfを使用してデータの取り出し
投稿者---たか(2003/10/10 23:26:51)


%sの代わりにあくまで%[^,],を使うとうまくいきます。

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

int main(void)
{
  int i;
  char a[128], b[128], c[128],d[128];
  char buf[128];

  *a = *b = *c = *d = '\0';
  
  strcpy(buf, "aaa,bbb,,ddd");

  i = sscanf(buf,"%[^,],%[^,],%[^,],%[^\n]", a, b, c, d);

  printf("%d %s %s %s %s\n", i, a, b, c, d);

  return 0;
}


No.9709

やはり上手いこといきませんでした。
投稿者---やくも(2003/10/11 13:42:48)


>%sの代わりにあくまで%[^,],を使うとうまくいきます。
>
><pre>#include <stdio.h>
#include <string.h>

int main(void)
{
int i;
char a[128], b[128], c[128],d[128];
char buf[128];

*a = *b = *c = *d = '\0';

strcpy(buf, "aaa,bbb,,ddd");

i = sscanf(buf,"%[^,],%[^,],%[^,],%[^\n]", a, b, c, d);

printf("%d %s %s %s %s\n", i, a, b, c, d);

return 0;
}</pre>

aaa,bbb,,ccc,,ddd,eee
aaa,bbb,111,ccc,222,ddd,eee
を1回のsscanfで取得するのはできませんでした。
やはり、NULLで引っ掛かってしまいます。
フィールド数は、分かっているので、stsstrやstrtokを使って
やってみます。

ありがとうございました・

No.9711

Re:sscanfを使用してデータの取り出し
投稿者---かずま(2003/10/11 15:05:50)


> 名と姓とサーバと数値7の内容をsscanfで取り出しています。
> 取り出す位置に値があると、ちゃんと取り出せますが、
> 姓が入っていない場合(NULL)の時は、それ以降が取りだせません。
> また、数値7を文字としてではなく数値とし取り出したいのですが、
> 変数を「double」として、sscanfでの呼び出し方法を「%f」とした
> のですが、上手く行きません。
#include <stdio.h>

#define FMT1 "%*d,%[^,],%[^,],%[^,],%*[^,],%*lf,%*lf,%*lf,%*lf,%*lf,%*lf,%lf"
#define FMT2 "%*d,%[^,],,%[^,],%*[^,],%*lf,%*lf,%*lf,%*lf,%*lf,%*lf,%lf"

int main(void)
{
    char buf[256], mei[256], sei[256], svr[256];  double size;

    while (fgets(buf, sizeof buf, stdin)) {
        sei[0] = '\0';
        if (sscanf(buf, FMT1, mei, sei, svr, &size) != 4 &&
            sscanf(buf, FMT2, mei, svr, &size) != 3) continue;
        printf("%-10s %-10s %-10s %8.3f\n", mei, sei, svr, size);
    }
    return 0;
}
これでよろしいでしょうか?