文字列から数値を抜き出す

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
mo-fu

文字列から数値を抜き出す

#1

投稿記事 by mo-fu » 14年前

いつも楽しくこのサイトを見させてもらってます。

早速ですが質問です。
読み込むtxt fileに

Frequencies -- 578.3447 599.0566 637.9770

のような”Frequencies --”から始まる文字列が(不定期に)何度も出現します。
”Frequencies --”の後の実数値の桁数は必ずしも上記の通りにはなっていません。
今は

コード:

double Extract(char *str)//strにはFrequencies --から始まる文字列が入っています
{
	
	char *cut;
	double energy;//文字列の数値を代入するためのものです
	
	 //文字列の確認
			cut = strtok(str," ");//スペースで分断
			while(cut != NULL){
				cut = strtok(NULL," ");//スペース以下の数字をhitに収納
				if(cut != NULL){
					energy = atof(cut);//文字列であるhitを数値に変
				}
			}
		return energy;
}
というような関数を持ちいてスペース部分でいちいち区切って得た数値を返しています。

まあ、これで一応は動いているのですが、文字列を前から読んでいって、数値(実数)だけを読み込んでポインタ(配列)に収納していくような関数ってありませんでしたっけ??

または違う方法で、もっとシンプルなやりかたあるよ!っていう意見をいただきたいです。

一応調べてみたのですが、これだ!と思うものが無かったので、初心者質問で恐縮なのですが皆さんの力を借りたいと思います。


環境はMicrosoft Visual C++ 2010で、C言語を用いています。

何分初心者ですので、つまらない質問かもしれませんが回答お待ちしてます。

box
記事: 2002
登録日時: 15年前

Re: 文字列から数値を抜き出す

#2

投稿記事 by box » 14年前

mo-fu さんが書きました: Frequencies -- 578.3447 599.0566 637.9770
先行する文字列は
"Frequencies --"
で固定ですか?

文字列の後ろに来る実数の個数は3個で固定ですか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

mo-fu

Re: 文字列から数値を抜き出す

#3

投稿記事 by mo-fu » 14年前

box さんが書きました: 先行する文字列は
"Frequencies --"
で固定ですか?
返信ありがとうございます。

文字列の後ろに来る実数の個数は3個で固定ですか?
先行する文字列は仰る通り、"Frequencies --"で固定ですが、文字列に続く実数の個数は1‐3個の幅があります。
3個で固定であればsscanfでの抜き出しも考えたのですが><

かずま

Re: 文字列から数値を抜き出す

#4

投稿記事 by かずま » 14年前

こんなんでどうでしょうか?

コード:

#include <stdio.h>
 
int Extract(const char *str, double *a, int n)
{
    int i, len;
    for (i = 0; i < n && sscanf(str, "%lf%n", &a[i], &len) == 1; i++)
        str += len;
    return i;
}
 
int main(void)
{
    double a[30];
    const char *str ="Frequencies -- 578.3447 599.0566 637.9770";
    int i, n = Extract(str + sizeof("Frequencies --"), a, 30);
    for (i = 0; i < n; i++) printf("%f\n", a[i]);
    return 0;
}

mo-fu

Re: 文字列から数値を抜き出す

#5

投稿記事 by mo-fu » 14年前

かずま さんが書きました:こんなんでどうでしょうか?

コード:

#include <stdio.h>
 
int Extract(const char *str, double *a, int n)
{
    int i, len;
    for (i = 0; i < n && sscanf(str, "%lf%n", &a[i], &len) == 1; i++)
        str += len;
    return i;
}
 
int main(void)
{
    double a[30];
    const char *str ="Frequencies -- 578.3447 599.0566 637.9770";
    int i, n = Extract(str + sizeof("Frequencies --"), a, 30);
    for (i = 0; i < n; i++) printf("%f\n", a[i]);
    return 0;
}
ほうほう!この場合

コード:

    double a[30];
となっているところを実際には動的に確保しといてやれば、柔軟に対応できるわけですね!
それにしても%nってこんな便利な使い方が出来たんですね!回答ありがとうございました。

ちなみに、Extract関数の中の引数(int n)に30を選んだのは何か理由がありますか??

ISLe
記事: 2650
登録日時: 15年前
連絡を取る:

Re: 文字列から数値を抜き出す

#6

投稿記事 by ISLe » 14年前

最大で3個程度なら。

コード:

#include <stdio.h>
int main(void)
{
	double a[3];
	const char *str ="Frequencies -- 578.3447 599.0566 637.9770";
	int i, n = sscanf(str + sizeof("Frequencies --"), "%lf %lf %lf", &a[0], &a[1], &a[2]);
	for (i = 0; i < n; i++) printf("%f\n", a[i]);
	return 0;
}
sscanfの戻り値で取り込めた数が分かりますけど。

mo-fu

Re: 文字列から数値を抜き出す

#7

投稿記事 by mo-fu » 14年前

ISLe さんが書きました:

コード:

#include <stdio.h>
int main(void)
{
	double a[3];
	const char *str ="Frequencies -- 578.3447 599.0566 637.9770";
	int i, n = sscanf(str + sizeof("Frequencies --"), "%lf %lf %lf", &a[0], &a[1], &a[2]);
	for (i = 0; i < n; i++) printf("%f\n", a[i]);
	return 0;
}
回答ありがとうございます!返信遅れてすみません。
確かに、この方法でやれば、無駄なメモリを使わなくてすみますね!勉強になります!
質問なんですが、この方法で行った時、もし数値が1つや2つで、EOFが返された場合は次の行のfor文の処理が行われ出すんですか?
それとも、このmain関数自体が終わるんでしょうか。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 文字列から数値を抜き出す

#8

投稿記事 by h2so5 » 14年前

mo-fu さんが書きました: 質問なんですが、この方法で行った時、もし数値が1つや2つで、EOFが返された場合は次の行のfor文の処理が行われ出すんですか?
それとも、このmain関数自体が終わるんでしょうか。
試せば分かります。

mo-fu

Re: 文字列から数値を抜き出す

#9

投稿記事 by mo-fu » 14年前

h2so5 さんが書きました: 試せば分かります。
ごもっとも(笑)
今のところ文字列に含まれる数値が3つでないデータが出てきてないので、出てきたときに試そうと思います!

閉鎖

“C言語何でも質問掲示板” へ戻る