データファイルの入力方法についての質問です。
フォーマットは以下↓の通り、1,2列目が日付,時間となっています。
(表記の都合上、半角スペースを_で置換しています。)
各行それぞれ3列目から最後の列までの和を計算したいと思っています。
問題点は以下の3点です
・1,2列目をとばしたい
・行によって列の数が異なる
・列の区切りのスペースの数がバラバラ
上の場合以外(つまりデータのみで列の数がそろっていて区切りも統一されている)
のファイルでしたらfscanfを使ってできます。
ご助言をよろしくお願いします。
2006/06/10____10:10:10____320.25____351.2____561.00___2646.00
2006/06/10____10:10:11____320.000___310.00___561.00
2006/06/10____10:10:12____320.000___310.00___561.00___2646.0
2006/06/10____10:10:13____320.000___310.00___561.0____2646.00
2006/06/10____10:10:14____320.0_____310.00___561.00___260.0
2006/06/10____10:10:15____310.00____561.00___2646.00
2006/06/10____10:10:16____320.00____310.00___561.00___2646.00
2006/06/10____10:10:17____320.000___310.00___561.0____2646.0
2006/06/10____10:10:18____310.0_____561.00___2646.00
2006/06/10____10:10:19____320.000___310.00___561.00___2646.0
2006/06/10____10:10:20____320.000___310.00___561.00___2646.00
_
No.7ベストアンサー
- 回答日時:
No.1です。
再び考えてみました。これなら理論的に何列・何行でも合計が計算できると思います。
ただ結果は出ますがプログラムがスマートでない!
もうちょっと考える余地があるかもしれません。
でも、何千・何万も列があるデータっていったい…
#include<stdio.h>
void main(void)
{
char date[12],time[10];
double data,total;
int col,c;
FILE *fp;
fp = fopen("sample.dat", "rt");
do {
fscanf(fp, "%s %s", date, time);
col = 0;
total = 0.0;
while ((c = getc(fp)) != '\n' && feof(fp) == 0) {
ungetc(c, fp);
col += fscanf(fp, "%lf", &data);
total += data;
}
if (col)
printf("%s %s (%d) %.3lf\n", date, time, col, total);
} while (feof(fp) == 0);
fclose(fp);
}
No.6
- 回答日時:
strtokなどを使わずにかいてみるとこんな感じになります。
空白(または改行)で区切られた文字列を「カラム」として、それを読み込んでくる手続きを使っています。
ungetcとかをつかっていて、教科書的に言うと悪いプログラムですが。
なお、質問の例示された以外の文字が混入しているとかカラム数が1の行があるとか、空行場合などの処理はしていません。
#include <stdlib.h>
#include <ctype.h>
#define MAXCOL 70000
double sums[MAXCOL];
#define MAXCOLLEN 1024
int getcolumn( char *data)
{
int ch;
do {
ch=getchar();
}while(ch==' ');
if(ch==EOF)
return -1;
if(ch=='\n')
return 0;
while(!isspace(ch)){
*data++ = ch;
ch=getchar();
if(ch==EOF)return EOF;
}
ungetc(ch, stdin);
*data = '\0';
return 1;
}
main()
{
int col, maxcol,r;
double num;
char data[MAXCOLLEN];
col=maxcol=0;
(void)getcolumn(data);
(void)getcolumn(data);
while((r=getcolumn(data))!=EOF) {
if(r==0) {
col=0;
(void)getcolumn(data);
(void)getcolumn(data);
} else {
sscanf(data,"%lf", &num);
sums[col]+= num;
printf("%d %g\n", col, sums[col]);
if(++col>maxcol)
maxcol=col;
}
}
for(col=0;col<maxcol;col++)
printf("%g\n", sums[col]);
return 0;
}
No.5
- 回答日時:
プログラミングの初心者というなら、プログラムを組むことそれ自体に意味があるならともかく、使う道具を選ぶのは大切かと。
たとえば awk なら、例にあるデータの場合
{
sum = 0
for (i=3; i<=NF; i++)
sum += $i
printf "%d行目のデータの合計は %6.3fです。", FNR, sum
}
こんだけですむんですが。
ありがとうございます。
そうですね、確かに同感です。
本質的でないところでつまずくのはもったいない気がします。
awkというものも調べてみます。
No.4
- 回答日時:
訂正
>for(i = 1; (data = strtok(NULL, TOKEN)) != NULL; i ++){
>if(i >= 2){
for(i = 2; (data = strtok(NULL, TOKEN)) != NULL; i ++){
if(i > 2){
No.2
- 回答日時:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define TOKEN " \n"
int main(void)
{
FILE *fp;
char str[256];
char *data;
int i, j;
float sum;
if((fp = fopen("data.txt","r")) == NULL){
puts(" File Open Error");
exit(1);
}
for(j = 1; fgets(str, 256, fp) != NULL; j ++){
if((data = strtok(str, TOKEN)) == NULL) continue;
printf(" Line(%d) ", j);
sum = 0;
for(i = 1; (data = strtok(NULL, TOKEN)) != NULL; i ++){
if(i >= 2){
printf(" %s ", data);
sum += atof(data);
}
}
printf(" Sum == %.2f\n", sum);
}
return 0;
}
No.1
- 回答日時:
C言語しかわかりませんが、自分の勉強の意味も含めてプログラムを書いてみました。
fscanf()で直接ファイルから読み込もうとすると改行も区切り文字とみなしてしまう
らしくうまくいきませんでした。
以下のように一度 fgets() で buf に行ごと読み込んでそれを sscanf() でデータに
分けると、うまく読み込めて読み込んだデータの個数も知ることができます。
以下はご質問のデータが sample.dat というファイルにあるとして各行を読み込み、
データの個数とそのデータの合計を表示するだけのものですが、参考になればと思い
そのままのかたちで載せておきます。
1・2列目は %*s で完全に無視しています。
行頭の空白が削られることがあるので見にくくなるかも知れません。
ただし、エラー処理が不十分であることや即値を使っているなど、結果は出るものの
プログラムとしては不完全です。
#include<stdio.h>
void main(void)
{
char buf[128];
float data[4],total;
int col,i;
FILE *fp;
fp = fopen("sample.dat", "rt");
while (fgets(buf, 128, fp) != NULL) {
col = sscanf(buf, "%*s %*s %f %f %f %f", data, data + 1, data + 2, data + 3);
printf("(%d) ", col);
total = 0.0;
for (i = 0; i < col; i++)
total += data[i];
printf("%9.3f\n", total);
}
fclose(fp);
}
回答ありがとうございます。
誤解を生んでしまう書き方をしてしまいましたが、
実際に扱うデータでは数字列の最大数は4ではありません(65536列以上ある行もある)。
ですので改行を読み込んだら~というものを使わなければいけないかなと思っています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
テキストファイル内に対して, ...
-
ファイル出力で改行を入れたい!
-
C言語 csv 配列
-
複数ファイルの同時読み込みの...
-
c言語 DFAのプログラム
-
日本語ファイル名のFTPについて
-
大量の入力ファイルを扱うとき...
-
C言語でファイル名を変数にした...
-
再検索プログラムについて
-
C言語を用いて、csvファイル内...
-
fopenでファイル名に、変数を使...
-
クリップボードから画像取得
-
C言語のファイル入出力の問題です
-
c言語でのfscanfについて
-
C言語でファイル読み書きを早く...
-
エラー C2664
-
行毎の黒のドット(ピクセル)...
-
2÷3などの余りについて
-
信頼区間の1.96や1.65ってどこ...
-
「Aに対するBの割合」と「Aに対...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
c言語でのfscanfについて
-
ファイルへの書込み処理が異常...
-
C言語でファイル読み書きを早く...
-
エラーがわかりません、、
-
日本語ファイル名のFTPについて
-
fopenでファイル名に、変数を使...
-
ファイル出力で改行を入れたい!
-
テキストファイル内に対して, ...
-
複数ファイルの同時読み込みの...
-
C言語の課題です
-
C言語を用いて、csvファイル内...
-
バイナリファイルの読み込み(C...
-
C言語にてXMLファイルから任意...
-
ファイルが読み込めない・・・
-
構造体のメンバにファイルポイ...
-
CRC32の計算方法
-
ファイルからCR/LFを除去したい
-
C言語におけるファイル読み込み...
-
C言語 csv 配列
-
エラー C2664
おすすめ情報