ページ 1 / 1
C言語 ファイル入出力
Posted: 2011年5月13日(金) 03:40
by ののき
数字のリストを読み込み、3で割り切れる数をkakikomi2,それ以外の数をkakikomi3に書き込むプログラムを作成しようと思うのですが、皆目見当がつきません。試しにfputsの余りで数を振り分けようと思ったのですが、
error C2296: '/' : 無効です。左オペランドには型 'int (__cdecl *)(const char *,FILE *)' が指定されています。
と出てしまい、エラーしてしまいます。
どのように修正すれば上手く作動するか、何卒ご教授お願いいたします。
コード:
#define _CRT_SECURE_NO_DEPRECATE 1 /* VisualC++2005 での警告抑制 */
#include <stdio.h>
int main(void)
{
FILE *fp, *fp2,*fp3;
char buf[81]; /* 読み込み用バッファ */
fp = fopen( "kakikomi.txt", "r" );
if( fp == NULL )
{
puts( "kakikomi.txtが開けません" );
return 1;
}
fp2 = fopen( "kakikomi2.txt", "w" );
if( fp2 == NULL )
{
puts( "kakikomi2.txtが開けません" );
return 1;
}
fp3 = fopen("kakikomi3.text","w");
if(fp3==NULL)
{
puts("kakikomi3.textが開けません");
return 1;
}
while( 1 )
{
if( fgets( buf, 81, fp ) == NULL ) /* 1行読み込み */
{
break; /* 末尾まで完了したか、エラー発生で終了 */
}
if(fputs%3=0)
fputs( buf, fp2 ); /* 1行書き込み*/
else
fputs( buf, fp3 ); /* 1行書き込み*/
}
fclose(fp3);
fclose( fp2 );
fclose( fp );
return 0;
}
Re: C言語 ファイル入出力
Posted: 2011年5月13日(金) 05:00
by パコネコ
コード:
if(fputs%3=0)
fputs( buf, fp2 ); /* 1行書き込み*/
else
fputs( buf, fp3 ); /* 1行書き込み*/
おそらく上のif文の中がまずいかもです。
エラーの文章的にもここだと思います。
そもそも宣言してないから変数で名前がかぶったって訳ではなさそうですし、
ミスですかね?
それと気になったのですが、
コード:
fp3 = fopen("kakikomi3.text","w");
if(fp3==NULL)
{
puts("kakikomi3.textが開けません");
return 1;
}
どうでもいいことかもですが、[.text]でOK?
========================
fputs%3=0
コレについては2つミスがあります。
きを付けてくださいね。
Re: C言語 ファイル入出力
Posted: 2011年5月15日(日) 03:14
by ののき
パコネコ様がご指導くださった問題点であるif文を変えてみました。正常に動作はするのですが、どうやら出力がkakikomi3にのみ反映されるようであり、上手く奇数、偶数に分かれて書き込まれません。
コード:
if(buf[81]%3==0)
fputs( buf, fp2 ); /* 1行書き込み*/
else
fputs( buf, fp3 ); /* 1行書き込み*/
また、kakikomi3.textは.txtの誤りのようでした。ご指摘ありがとうございます。
Re: C言語 ファイル入出力
Posted: 2011年5月15日(日) 03:23
by h2so5
・bufは文字列ですのでそのまま計算することができません。
計算するためには整数に変換する必要があります。
・buf[81]は配列の範囲外の何も関係の無い場所を指しています。
Re: C言語 ファイル入出力
Posted: 2011年5月15日(日) 06:49
by box
ののき さんが書きました:
正常に動作はするのですが、どうやら出力がkakikomi3にのみ反映されるようであり、上手く奇数、偶数に分かれて書き込まれません。
正常に動作する、の意味を取り違えています。
仕様どおりに動いていないのですから、正常に動作してはいません。
Re: C言語 ファイル入出力
Posted: 2011年5月15日(日) 12:04
by パコネコ
参照:c言語文字列講座
http://tkmakwins15.tuzikaze.com/contents/string1.htm
さすがにbuf[81]はまずいです。
配列が宣言される場合。(いや、”される”じゃなくて”する”場合かな?)
の場合、使ってもいいのは、
buf[0~N-1]までです。
つまりこの場合Nは81なので、buf[0~80]までしか使ってはいけません。
とりあえず配列についてはまた勉強しておいてください。
本題ですが、文字列bufの中には数字が入っているんですよね。
その数字を数値に変換しなければ少し難しいかと思われます。
なので、数字を数値に変換してくれる関数が下のものです。
コード:
stdlib.h
int atoi(const char *string);
long atol(const char *string);
double atof(const char *string);
これらの関数が役立ちます。
使い分けは、intがかえってきてほしかったらatoi,実数がかえってきてほしかったらatofです。
(かえってきてほしいというか何が入っているかが問題だけど)
この場合あまりの数が欲しいのでおそらくatoiを使えば大丈夫でしょう。
(中身が実数なら話は変わるけど)
関数の使い方はわかりますか?
一応参照の下の方にこの関数が乗っているので読んでみてください。
特に1番の文字列の基本を。
(使用例とかはのってないからちょっと心配ですが...ほかにも文字列関係の者が乗っているので。)
使用例
atoi(buf);
ってかいたらbufの中身が整数になってかえってきます。(多分...自分じゃあんまり使わないですが...)
============
>atoiやatofはエラーチェックがまったくできないので使ってはならない関数です。
たかぎさん
ご指摘ありがとうございました。
ののきさん
すいません。中途半端な情報のせてしまいまして。
Re: C言語 ファイル入出力
Posted: 2011年5月15日(日) 12:18
by たかぎ
パコネコ さんが書きました:使い分けは、intがかえってきてほしかったらatoi,実数がかえってきてほしかったらatofです。
atoiやatofはエラーチェックがまったくできないので使ってはならない関数です。
strtolやstrtodを使うようにしましょう。
もし仮に、入力の整合性を別のところで保証できるなど、エラーチェックが必要ないということであれば、fscanfを使った方が簡単です。
Re: C言語 ファイル入出力
Posted: 2011年5月23日(月) 02:59
by ののき
strolを使い、codeを変更してみたところ、
error C2664: 'strtol' : 2 番目の引数を 'int' から 'char **' に変換できません。(新しい機能 ; ヘルプを参照)
整数型からポインター型への変換には reinterpret_cast、C スタイル キャストまたは関数スタイル キャストが必要です。
が出てしまいました。できれば、キャストを使わず、codeを書きたいのですがどのように変更すればよいでしょうか。ご指導お願いいたします。
コード:
#define _CRT_SECURE_NO_DEPRECATE 1 /* VisualC++2005 での警告抑制 */
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp, *fp2,*fp3;
char buf[81]; /* 読み込み用バッファ */
fp = fopen( "kakikomi.txt", "r" );
if( fp == NULL )
{
puts( "kakikomi.txtが開けません" );
return 1;
}
fp2 = fopen( "kakikomi2.txt", "w" );
if( fp2 == NULL )
{
puts( "kakikomi2.txtが開けません" );
return 1;
}
fp3 = fopen("kakikomi3.txt","w");
if(fp3==NULL)
{
puts("kakikomi3.txtが開けません");
return 1;
}
while( 1 )
{
if( fgets( buf, 80, fp ) == NULL ) /* 1行読み込み */
{
break; /* 末尾まで完了したか、エラー発生で終了 */
}
int num;
num=strtol(buf,80,fp);
if(num%3==0)
fputs( buf, fp2 ); /* 1行書き込み*/
else
fputs( buf, fp3 ); /* 1行書き込み*/
}
fclose(fp3);
fclose( fp2 );
fclose( fp );
return 0;
}
Re: C言語 ファイル入出力
Posted: 2011年5月23日(月) 03:48
by パコネコ
キャストを使わないなら素直にfscanf使った方がよろしいかと思います。
参考サイト様<C言語編 第36章 テキストファイルの読み書き②>
http://www.geocities.jp/ky_webid/c/036.html
コード:
num=strtol(buf,80,fp);
問題があるのはここですね。
この場合strtolの使い方を間違われているようです。
(私もさっき初めて使い方調べてましたが (^^;) )
参考サイト様はこちら<strtol>
http://www9.plala.or.jp/sgwr-t/lib/strtol.html
上のサイト様によれば、
コード:
【書式】
#include <stdlib.h>
long strtol(const char *s, char **endptr, int base);
となっております。
引数の最初の場所にある「const char *s」は、文字列が入っている変数(配列)を入れる場所です。
今回の場合ですと、bufを入れる場所でしょうか。
2つ目の引数の「 char **endptr」は、このプログラムでは必要ないように思えます。
なので、NULLとでも入れておけばいいと思います。
そして、3つ目の引数である「int base」は、何に変換するかですね。
いっそ10とでも書いとけばいいと思いますが、使ったことないので、一度調べてみてから使ってみてください。
Re: C言語 ファイル入出力
Posted: 2011年5月29日(日) 20:49
by ののき
パコネコ様のご指導通り、
コード:
num=strtol(buf,80,fp);
↓
num=strtol(buf,NULL,10);
にしたところ、期待通りに動作いたしました。
かなり苦労していたので、嬉しい限りです。本当にありがとうございます。