こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

スペースで区切って数字を入力

スペースで区切られた5個の数字を端末から入力し、表示するプログラムが書けずに困っています。
#include<stdio.h>
int main(){
char str[5]=={%lf %lf %lf %lf %lf,&a,&b,&c,&d,&e}
などと書いていってもよさそうなのですが、数を5→10などと増やしていくと初期化子の数が多すぎでコンパイルで通りません。

配列を用いたよい方法はないでしょうか?

投稿日時 - 2007-04-29 13:46:03

QNo.2959473

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

strtokはあまり使うことが推奨されない関数です。

Manpage of STRTOK
http://www.linux.or.jp/JM/html/LDP_man-pages/man3/strtok.3.html
のバグの部分を参照してください。

対策としてはこういう関数を仕立ててみるとか。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

int
fill_array(char *buf, double *target, size_t array_max)
{
int count = 0;
int maxcount = (int)array_max;
char *p, *q;

fprintf(stderr, "%s: buf=%p, array_max=%d\n",
__FUNCTION__, buf, array_max);
if (maxcount <= 0)
return -1;

for (count=0, p=buf; count < maxcount; count++) {
double val;
val = strtod(p, &q);
fprintf(stderr, "%s: get %f\n", __FUNCTION__, val);
if ((val==0 && p==q) || !*q || !isspace(*q))
break;
target[count] = val;
p=q;
}

return count;
}

int
main()
{
int count;
int i;
char linebuf[1024];
double numbers[10];
double sum;

fgets(linebuf, sizeof linebuf, stdin);
fprintf(stderr, "input = %s\n", linebuf);
count = fill_array(linebuf, numbers, (sizeof numbers/sizeof numbers[0]));
fprintf(stderr, "count=%d\n", count);

for (i=0, sum=0; i<count; i++) {
printf("%02d: %f\n", i, numbers[i]);
sum += numbers[i];
}

printf("avarage = %f\n", sum/count);

return 0;
}

サンプルのためエラーチェックが甘かったりしますので使うなら
適当に直してくださいませ。

投稿日時 - 2007-04-30 00:44:12

ANo.2

★fgets 関数で読み取った文字列をスペースで分解すればよい。
・過去に似たような質問がありました。
 http://oshiete1.goo.ne.jp/qa2749340.html→『fgetsなどをもちいて「改ページ」までの文字列を読み込みたい』
 です。この質問では文字列を『改ページ』文字で分割するにはどうすればよいか、という事でした。
 今回はスペース文字ですので『改ページ』文字をスペース文字に置き換えて読んでみて下さい。→回答者 No.3
 サンプル・ソースの『改ページのコード』の部分をスペース文字(0x20)にすれば分割された文字列
 が seek ポインタで得られます。
・今回は strtok 関数での分割を下に紹介します。どちらでも分割できますのでお好きな方法で。

サンプル:
char buff[ 256 ];
char *line;

if ( fgets(buff,sizeof(buff),stdin) != NULL ){ ←端末からの入力
 for ( line = strtok(buff," ") ; line != NULL ; line = strtok(NULL," ") ){
  /*
  分割された文字列 line が得られる
  */
 }
}

解説:
・fgets() 関数で半末から複数のスペースで区切られた文字列を取得します。
 その後、for 文中で strtok() 関数でスペースで区切られた文字列を分割しています。
 strtok() の使い方は、
 1回目…strtok( 分割する文字列, 区切り文字群 )
 2回目…strtok( NULL, 区切り文字群 )
 3回目…strtok( NULL, 区切り文字群 )
   :
 n回目…strtok( NULL, 区切り文字群 )
 と最初の1回目だけ分割する文字列を第1引数に指定します。→内部に登録される。
 その後、区切り文字群を指定することでどんどん分割できます。
 区切り文字群は毎回同じでも、違っても良い。→今回はすべてスペース文字なので同じ指定です。

その他:
・for 文中で分割された文字列 line を printf 関数など表示すれば良い。
 あと端末からの入力を繰り返すのならば、fgets() 関数の部分を if → while に変更すれば
 繰り返します。
・以上。fgets() と strtok() 関数の組み合わせでした。→他にも strchr での分割もあります。

参考URL:http://oshiete1.goo.ne.jp/qa2749340.html

投稿日時 - 2007-04-29 16:59:33

ANo.1

strtok() じゃだめですか
http://www9.plala.or.jp/sgwr-t/lib/strtok.html

投稿日時 - 2007-04-29 13:53:33

補足

ご回答ありがとうございます。strtok()を使用したものも考えて見ます。
fgets()とsscanf()を組み合わせて使用する、という場合はどうなるでしょうか?

投稿日時 - 2007-04-29 14:21:26

あなたにオススメの質問