マンガでよめる痔のこと・薬のこと

過去数十年分(約30年)1時間毎のデータがあるcsvファイルから、各年の3月のデータを読み取りたいです。

ファイルの中身は
「1979/1/1 1:00, 0, 8, 1
 1979/1/1 2:00, 0, 8, 1
 :省略
 2016/12/31 10:00, 1, 8, 1
 2016/12/31 11:00, 1, 8, 1」

以下のプログラムから、どのように各年の5月のデータだけを抽出するように書き換えれば良いか教えていただきたいです。よろしくお願いします。

#include <stdio.h>

int main(){
FILE *fp;
char *fname = "data.csv";
int ret;
char buf[4][20];
double data1[1];
int data2[2];
int yr, mo, dy, hr, mn;

fp = fopen( fname, "r" );
if( fp == NULL ){
printf( "%sファイルが開けません\n", fname );
return -1;
}

printf("\n");

fscanf(fp, "%[^,],%[^,],%[^,],%s", buf[0], buf[1], buf[2],buf[3]);
printf("%s %s %s %s\n",buf[0], buf[1], buf[2],buf[3]);


while( (ret=fscanf(fp, "%d/%d/%d %d:%d,%lf,%d,%d", &yr, &mo, &dy, &hr, &mn, &data1[0], &data2[0],&data2[1])) == 8){
printf("%d %d %d %d %d %lf %d %d\n", yr, mo, dy, hr, mn, data1[0], data2[0],data2[1]);
}

printf("\n");
fclose( fp );
}

A 回答 (3件)

OSが不明ですが、linuxなら


grep /5/ data.csv
で5月のデータのみ抽出できます。
    • good
    • 0

これはC言語でやれという課題なのでしょうか。


そうでなければ、perlとかrubyで3月(5月?)のデータ(行)を抜き出す方が簡単かと。
    • good
    • 0

ファイルの先頭から1行づつ読み込んで、3月か5月(質問からどっちかわからない)のデータだけ処理すれば良いのでは。


whileループ内のfscanfとfprintfの間に月をチェックするif文を入れる。
fscanf文はどうかと思うけど。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

Q最も高い身長を表示するプログラム

5人分の身長から最も高い身長を表示するプログラムをつくったのですが、エラーがでて実行できません。改善すべきところを教えてください。お願いします。
int main(void)
{
double a[5], max = 0;
int i;

for (i = 1; i <= 5; i++)
{
a[i] = 0;
}
printf("数値を5つ入力してください。\n");

for (i = 1; i <= 5; i++)
{
scanf("%lf", &a[i]);
}

for (i = 1; i <= 5; i++)
{
if (a[i] > max)
max = a[i];
}

printf("最も高い身長は%fです\n", max);

return 0;
}

Aベストアンサー

double a[5] ;
と宣言したら、安全に使えるのは a[0] 〜 a[4] です。

なので、このプログラムを安全なものにするなら
・double a[5]はそのまま、 i=0;i<5;i++ にして、 i=0〜4 の範囲で使う
・「i = 1; i <= 5; i++は変えない」 のなら
 ・ i=1〜5を、 0〜4 に対応させて使う
   単純明快なのは、 a[i-1] とすること
 ・double a[5+1] と宣言して、a[5] を安全に使えるようにする。
   a[0] が無駄になるけど気にしない

QC言語 時刻差分の算出方法

教えて下さい。

C言語を用いてプログラミングをしています。
時刻をマイコン内部で1分毎にカウントしていますが、
外部入力があった際は、時刻を外部入力値に更新します。

時刻は以下の構造体で構成しています。

[年] 0x00~0x63 未設定:0x00
[月] 0x01~0x0c 未設定:0x00
[日] 0x01~0x1f 未設定:0x00
[時] 0x00~0x17 未設定:0xff
[分] 0x00~0x3b 未設定:0xff
[曜] 0x01~0x07 未設定:0x00

-----------------------------------------------------
typedef struct {
 unsigned char year_dt;
 unsigned char month_dt;
 unsigned char day_dt;
 unsigned char hour_dt;
 unsigned char min_dt;
 unsigned char week_dt;
}CALENDER_INFO;

CALENDER_INFO Calender_Before;
CALENDER_INFO Calender_After;

void Calender_Update(void){

 /* 処理前の時刻取得 */
 Calender_Before= Calender_Data;

 if(FLG_ON == F_SOUSA_A){
  Calender_Data = Calender_a;   /* 外部操作[a]データ反映 */
 }else{
  if(FLG_ON == F_SOUSA_B){
   Calender_Data = Calender_b;   /* 外部操作[b]データ反映 */
  }else{
   Add_1min_Calender();     /* 操作無ければ1分進める */
  }
 }

 /* 処理後の時刻取得 */
 Calender_After = Calender_Data;

 /* 差分算出 */
 ???????

return;
}
-----------------------------------------------------

時刻は[正]又は[負]のどちらの方向にも変更される可能性があります。

処理前の時刻情報と処理後の時刻情報をメンバ毎に演算するしかないのでしょうか?
演算の際に時刻の繰り上がりや繰り下がりを考慮しますと、
膨大なif文だらけになりバグが多発していまうのではないかと懸念しております。

初歩的な質問で申し訳ありませんが、
時刻計算にお詳しい方がいらっしゃいましたらご教示宜しくお願い致します。

教えて下さい。

C言語を用いてプログラミングをしています。
時刻をマイコン内部で1分毎にカウントしていますが、
外部入力があった際は、時刻を外部入力値に更新します。

時刻は以下の構造体で構成しています。

[年] 0x00~0x63 未設定:0x00
[月] 0x01~0x0c 未設定:0x00
[日] 0x01~0x1f 未設定:0x00
[時] 0x00~0x17 未設定:0xff
[分] 0x00~0x3b 未設定:0xff
[曜] 0x01~0x07 未設定:0x00

-----------------------------------------------------
typedef struct {
 unsigned cha...続きを読む

Aベストアンサー

日付時刻の構造体は自作のものでなきゃいけない理由はあるのでしょうか?
tm構造体を使えば二つの時間の差も簡単に出せます

time関数を使えるならtm構造体を使わず差を算出できます

文章で書くとややこしくなりそうなので参考サイトを貼ります
http://www.c-tipsref.com/tips/time/time.html
http://www1.cts.ne.jp/~clab/hsample/Time/Time5.html

Q開発業務で使用するC/C++の規格(素朴な疑問)

趣味プログラマの素朴な疑問です。

開発業務でCやC++を使用されている方もいらっしゃると思います。
ネットをみているとCやC++にいろいろな規格があるというのを目にします。
例えばWikipediaを参考にすると
C言語:C89/C90、C99、C11
C++:C++98、C++03、C++11、C++14

今現在、使用されているのはどの規格が多いのですか?
分野で異なったりするのですか?
どの規格を使用するというのは客先からの指定となるのですか?
客先からの指定がない場合は、社内規定でこの規格を使用すると決められているのですか?

お手隙の際にご回答いいただければ嬉しいです。

Aベストアンサー

まず、お客様から指定がある場合はそれが最優先となります。お客様も開発系の仕事をされている場合、指定される可能性が高いですが、そうでない場合はC/C++の規格といった細かいことを指定されるのはまずありません。

お客様から指定が無い場合は、開発チームで決めることになります。ここは開発チームによって大きく方針が違うところかと思いますが、過去に開発経験のある開発環境を踏襲する場合が多いです。同じにした方が、新しいことを覚え直す時間がかからないことと、場合によっては過去に開発した資源を流用できるからです。

会社によっては新しい技術を積極的に学んでいこうというところもあるかもしれませんが、常に新しい技術にキャッチアップするとそれだけ学習する時間なども必要なため、開発スケジュール、開発予算が必要となります。ただ、長期的な視点でみると開発予算をかけてでも、開発メンバーが新しい技術を学べるのは良いことなので、ここをどうするかは各会社によって異なると思います。

QC#プログラミング、少数の取り扱い方がわかりません

説明のしかたが下手で申し訳ないのですが

double型の数値で0.999999999999......と続く数値があったとして、この数値が1.0として扱われるのは小数第何位からですか?

また、1.0に近似してほしくないときはどうしたらいいですか?
C#でプログラミングをしています

Aベストアンサー

やろうとしていることは
lim_(x→0) f(x) = 1
で、 xを0に近付けつつ、f(x) を計算する、という感じなのでしょうか。


方法は3つあります。
(1) 計算式を工夫する。
0.999... だと 10^-15程度までしか正しくありませんが
0.000 .... 1 → 1.0 * 10^-n だと、10^-nの桁から15桁程度までの精度があります。
式を工夫して、計算結果が1ではなく、0に向うようにすることで、精度よく計算できるかもしれません
例)
g(x)=1-f(x) を求める。 ※「桁落ち」に注意


(2)十分な精度のある型を使う
https://ja.wikipedia.org/wiki/%E4%BB%BB%E6%84%8F%E7%B2%BE%E5%BA%A6%E6%BC%94%E7%AE%97
自作するか、既存のものを使う


(3)計算自体に意味があるのか、考えてみる。

QC言語について質問お願いします まだ勉強中なのでご指導よろしくお願いします str1=big str

C言語について質問お願いします

まだ勉強中なのでご指導よろしくお願いします

str1=big
str2=city
str3=bigcity

という結果にしたいのですが下のような結果になり困っております(´;Д;`)

もっといい書き方もあるかもしれませんが、今書いてあるコードを活かして訂正して結果通りになるにはどうすればいいでしょうか?!

その他アドバイスありましたら先輩方よろしくお願いしますm(_ _)m

Aベストアンサー

一つ訂正します
誤) char str1[4]={"big"},str2[4]={"city"}, str3[1]={0};
正) char str1[4]={"big"},str2[5]={"city"}, str3[1]={0};

ベテランでもこういう単純な間違いをすることがあります。
間違えもいいんです。それに気付いて直せれば。

ダメなときは、どこでダメになっているかを調べ、何故ダメになるかを調べ、どうすればダメじゃなくなるかを考えます。
これはベテランでも初心者でも変わりません。



原因は str3[1],str3[2] ...と範囲外に書き込んだことです。
例えるなら、「子供に紙とクレヨン渡したら、調子にのって床にまで絵を描いてしまった」状態です。
よって、対策は
・これらに書きこまないようにする。つまり、配列に収まる大きさの文字列にする
 (例えるなら「紙の外に描かないような小さな絵にする」)
・これらが書き込まれても問題ない状態にする。つまり、配列の大きさを十分に大きくする
 (例えるなら「絵が入るくらいの大きな紙にする」)
のどちらか、となります。

今回の場合、書き込みたい文字列が決まっているので、前者の「収まる文字列にする」という方法は使えません。
よって、後者の「文字列が収まる配列にする」が正解になります。

配列の大きさの指定方法はわかりますね?

一つ訂正します
誤) char str1[4]={"big"},str2[4]={"city"}, str3[1]={0};
正) char str1[4]={"big"},str2[5]={"city"}, str3[1]={0};

ベテランでもこういう単純な間違いをすることがあります。
間違えもいいんです。それに気付いて直せれば。

ダメなときは、どこでダメになっているかを調べ、何故ダメになるかを調べ、どうすればダメじゃなくなるかを考えます。
これはベテランでも初心者でも変わりません。



原因は str3[1],str3[2] ...と範囲外に書き込んだことです。
例えるなら、「子供に紙とクレヨン渡...続きを読む

Q平均身長のプログラミング

平均身長を求めるプログラミングがよくわかりません。
5人分の身長を打ち実行したところ、このプログラムではうまくでませんでした。
どなたか教えてください。よろしくお願いします。
int main(void)
int i;
double sum, x, m;

sum = 0;

for (i = 1; i <= 5; i = i + 1) {
scanf("%d", &x);
sum = sum + x;
}

m=sum / 5;
printf("平均は%fです\n", m);

Aベストアンサー

scanf("%d", &x);

scanf("%lf", &x);
に変えてください。

QC言語 構造体の中に共用体を定義した変数の初期化に関して

C言語のコンパイルエラーに関する質問です。
以下のような構造体の中に共用体を作成して、constで初期値を入れておきたいと考えています。
機械に適用する初期パラメータのような感じです。
「初期化子が多すぎます。」というコンパイルエラーがでるのですが、どこが多いのかわかりません。
どう修正すれば良のか教えていただけないでしょうか?

// 構造体定義
typedef struct {
Uint16_t time;
Uint8_t mode;
Uint16_t xxxx;
Uint16_t zzzz;
}PrgPatternA_t;

typedef struct {
Uint16_t time;
Uint8_t mode;
Uint16_t yyyy;
}PrgPatternB_t;

typedef struct {
Uint8_t pattern;
union {
PrgPatternA_t param_a[3];
PrgPatternB_t param_b[2];
}param;
} Program_t;

// 変数定義
EsCourseProgram_t ES_COURSE_PROG_DATA = {
PATTERN_A,
{ // Aパターン
// time mode xxxx yyyy
{ 10, MODE_A, 100, 50},
{ 10, MODE_A, 100, 50},
{ 10, MODE_A, 100, 50}
}
}

C言語のコンパイルエラーに関する質問です。
以下のような構造体の中に共用体を作成して、constで初期値を入れておきたいと考えています。
機械に適用する初期パラメータのような感じです。
「初期化子が多すぎます。」というコンパイルエラーがでるのですが、どこが多いのかわかりません。
どう修正すれば良のか教えていただけないでしょうか?

// 構造体定義
typedef struct {
Uint16_t time;
Uint8_t mode;
Uint16_t xxxx;
Uint16_t zzzz;
}PrgPatternA_t;

typedef struct {
Uint16_t ti...続きを読む

Aベストアンサー

どの初期値がどのメンバーに対応するかをじっと見ていくと, {} が 1つ足らない. つまり初期化子は
{
PATTERN_A,
{ // Aパターン
// time mode xxxx yyyy
{
{ 10, MODE_A, 100, 50},
{ 10, MODE_A, 100, 50},
{ 10, MODE_A, 100, 50}
}
}
}
でないといけない.

どこかの {} を忘れていたんだと思う. 共用体を初期化するときの {} かなぁ?

QCのプログラムに無性にイライラするのはおかしいですか?

CQ出版のインタフェース 2017-5 の記事のプログラム例に
for( i=0; i<256; i++){
 for( y =0; y < Y; y++ ){
  for( x = 0; x < X; x++){
   p[0] = img -> imageData[img->widthStep* y + x*3 ]; //B(青色)
   if(p[0]==i){hn[i]++;}
  }
 }
}
がありました。このリストを見て、無性にイライラするのは私だけでしょうか?

なぜ、i,y,x の3重のループで処理しないといけないのか、y,xの2重ループで十分ではないかと思います。

for( y =0; y < Y; y++ ){
 for( x = 0; x < X; x++){
  p[0] = img -> imageData[img->widthStep* y + x*3 ];  //B(青色)
  hn[ p[0] ]++;
 }
}

3重にするならせめて、y,x,i の順にしてp[0]への代入は1回で済ませればと思います。

for( y =0; y < Y; y++ ){
 for( x = 0; x < X; x++){
  p[0] = img -> imageData[img->widthStep* y + x*3 ];  //B(青色)
  for( i=0; i<256; i++){
     if(p[0]==i){hn[i]++;}
  }
 }
}

最近のコンパイラの最適化では、私の書いたようなコーディング(修正?)は無意味なのでしょうか?

CQ出版のインタフェース 2017-5 の記事のプログラム例に
for( i=0; i<256; i++){
 for( y =0; y < Y; y++ ){
  for( x = 0; x < X; x++){
   p[0] = img -> imageData[img->widthStep* y + x*3 ]; //B(青色)
   if(p[0]==i){hn[i]++;}
  }
 }
}
がありました。このリストを見て、無性にイライラするのは私だけでしょうか?

なぜ、i,y,x の3重のループで処理しないといけないのか、y,xの2重ループで十分ではないかと思います。

for( y =0; y < Y; y++ ){
 for( x = 0; x < X; x++)...続きを読む

Aベストアンサー

利点を考えてみました


これを並列処理したときに
スレッド0: hn[0] に p[0] = 0 をカウント
スレッド1: hn[1] に p[0] = 1 をカウント
...
とすれば、
・img -> imageData は読み出すだけなので衝突しない
・hn[i] でアクセスする領域は、スレッド毎に i が違うので、同じ箇所に書き込まれることはない。
となり、排他処理が不要となります。
(もちろん、x,y,i,p[0]はスレッドでローカルな変数とします)

ただ、並列処理のオーバーヘッドや同時並列処理数等を考えると、こんな並列処理はしない方が効率的です。


あるいは、hn[]がシークに時間がかかる領域の場合、
hn[p[0]) で毎回違う位置を探しに行って、その時間が無視できないほどだったら、
先にhnを決めてしまった方が速くなるでしょう。

こちらも、非現実的です。

Qc言語のプログラミングの問題で50以下の正の偶数を降順(大きい順)で表示するプログラムを作成できる方

c言語のプログラミングの問題で50以下の正の偶数を降順(大きい順)で表示するプログラムを作成できる方お願いします

Aベストアンサー

No3の方から既に回答がでていますが、別解です。
#include <stdio.h>

int main()
{
printf("50\n");
printf("48\n");
printf("46\n");
printf("44\n");
printf("42\n");
printf("40\n");
printf("38\n");
printf("36\n");
printf("34\n");
printf("32\n");
printf("30\n");
printf("28\n");
printf("26\n");
printf("24\n");
printf("22\n");
printf("20\n");
printf("18\n");
printf("16\n");
printf("14\n");
printf("12\n");
printf("10\n");
printf("8\n");
printf("6\n");
printf("4\n");
printf("2\n");
return 0;
}

以下、実行結果です。
------------------------------------
50
48
46
44
42
40
38
36
34
32
30
28
26
24
22
20
18
16
14
12
10
8
6
4
2

No3の方から既に回答がでていますが、別解です。
#include <stdio.h>

int main()
{
printf("50\n");
printf("48\n");
printf("46\n");
printf("44\n");
printf("42\n");
printf("40\n");
printf("38\n");
printf("36\n");
printf("34\n");
printf("32\n");
printf("30\n");
printf("28\n");
printf("26\n");
printf("24\n");
printf("22\n");
printf("20\n");
printf("18\n");
printf("16\n");
printf("14\n");
printf("12\n");
printf("10\n");
printf("8\n");
printf("6\n");
printf("...続きを読む

QC言語で、べき乗の計算をするプログラムについてです

X^8の計算を、掛け算を使わずに、足し算と引き算を使って計算するプログラムを作成するというものです。
足し算のみを使ってべき乗の計算をするプログラムは以下のソースコードの様にできたのですが、足し算と引き算の両方ともを使って計算するプログラムがわかりません。
べき乗の計算をどのように考えれば、足し算と引き算の両方を使って計算できるのか教えてください。
以下、足し算のみを使って計算するプログラムのソースコードです。
・・・ソースコード・・・
#include<stdio.h>

int main(void) {

int i, j, k;
i = 0; ///①Xの加算回数の値を保持する変数iを0に初期化する。///
j = 0; ///②X^2の加算回数の値を保持する変数jを0に初期化する。///
k = 0; ///③X^4の加算回数の値を保持する変数kを0に初期化する。///
double X, goukei1, goukei2, goukei3;
X = 0;
goukei1 = 0; ///④X^2の計算値を保持する変数goukei1を0に初期化する。///
goukei2 = 0; ///⑤X^4の計算値を保持する変数goukei2を0に初期化する。///
goukei3 = 0; ///⑥X^8の計算値を保持する変数goukei3を0に初期化する。///

printf("X=");
///数値Xを入力///
scanf_s("%lf", &X);

///⑦iがX以下か判定し、真ならば⑧~⑨を繰り返し、偽ならば繰り返しを終了する。///
for (i = 0; i < X; i++) { ///⑨iに1を加算する。///
goukei1 += X; ///⑧goukei1にXを加算する。///
}

///⑩jがgoukei1以下か判定し、真ならば⑪~⑫を繰り返し、偽ならば繰り返しを終了する。///
for (j = 0; j < goukei1; j++) { ///⑫jに1を加算する。///
goukei2 += goukei1; ///⑪goukei2にgoukei1を加算する。///
}

///⑬kがgoukei2以下か判定し、真ならば⑭~⑮を繰り返し、偽ならば繰り返しを終了する。///
for (k = 0; k < goukei2; k++) { ///⑮kに1を加算する。///
goukei3 += goukei2; ///⑭goukei3にgoukei2を加算する。///
}
///最終的な計算結果を出力///
printf("X^8=%f", goukei3);

return 0;
}

X^8の計算を、掛け算を使わずに、足し算と引き算を使って計算するプログラムを作成するというものです。
足し算のみを使ってべき乗の計算をするプログラムは以下のソースコードの様にできたのですが、足し算と引き算の両方ともを使って計算するプログラムがわかりません。
べき乗の計算をどのように考えれば、足し算と引き算の両方を使って計算できるのか教えてください。
以下、足し算のみを使って計算するプログラムのソースコードです。
・・・ソースコード・・・
#include<stdio.h>

int main(void) {
...続きを読む

Aベストアンサー

「引き算を使え」という問題の意図がよくわかりませんが、単純にfor文のカウンタ(質問文ではi, j, k)を加算ではなく減算でカウントするっていう意味だったりしないでしょうか。

ところで、X^8 = ((X^2)^2)^2 というアイデアは数学的には賢いやり方ですが、
足し算縛りのプログラムで作ると実は計算量は大きくなると思います。
X^8 = ((((((X*X)*X)*X)*X)*X)*X)*X の方が、実は計算回数が少なくて済みます。
X=10の場合、前者は10,110回、後者は70回の足し算になります。


人気Q&Aランキング