C言語 ファイル入出力

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

C言語 ファイル入出力

#1

投稿記事 by ののき » 8年前

数字のリストを読み込み、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;
}

アバター
パコネコ
記事: 139
登録日時: 9年前
住所: 大阪

Re: C言語 ファイル入出力

#2

投稿記事 by パコネコ » 8年前

コード:

        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言語 ファイル入出力

#3

投稿記事 by ののき » 8年前

パコネコ様がご指導くださった問題点であるif文を変えてみました。正常に動作はするのですが、どうやら出力がkakikomi3にのみ反映されるようであり、上手く奇数、偶数に分かれて書き込まれません。

コード:

if(buf[81]%3==0)
		fputs( buf, fp2 );      /* 1行書き込み*/
		else
		fputs( buf, fp3 );      /* 1行書き込み*/
また、kakikomi3.textは.txtの誤りのようでした。ご指摘ありがとうございます。

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

Re: C言語 ファイル入出力

#4

投稿記事 by h2so5 » 8年前

・bufは文字列ですのでそのまま計算することができません。
計算するためには整数に変換する必要があります。

・buf[81]は配列の範囲外の何も関係の無い場所を指しています。

box
記事: 1746
登録日時: 9年前

Re: C言語 ファイル入出力

#5

投稿記事 by box » 8年前

ののき さんが書きました: 正常に動作はするのですが、どうやら出力がkakikomi3にのみ反映されるようであり、上手く奇数、偶数に分かれて書き込まれません。
正常に動作する、の意味を取り違えています。
仕様どおりに動いていないのですから、正常に動作してはいません。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
パコネコ
記事: 139
登録日時: 9年前
住所: 大阪

Re: C言語 ファイル入出力

#6

投稿記事 by パコネコ » 8年前

参照:c言語文字列講座
http://tkmakwins15.tuzikaze.com/contents/string1.htm

さすがにbuf[81]はまずいです。
配列が宣言される場合。(いや、”される”じゃなくて”する”場合かな?)

コード:

char buf[N];
の場合、使ってもいいのは、
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はエラーチェックがまったくできないので使ってはならない関数です。
たかぎさん
ご指摘ありがとうございました。
ののきさん
すいません。中途半端な情報のせてしまいまして。
最後に編集したユーザー パコネコ on 2011年5月15日(日) 12:25 [ 編集 3 回目 ]
ニャン!!\(゜ロ\)(/ロ゜)/

たかぎ
記事: 328
登録日時: 9年前
住所: 大阪
連絡を取る:

Re: C言語 ファイル入出力

#7

投稿記事 by たかぎ » 8年前

パコネコ さんが書きました:使い分けは、intがかえってきてほしかったらatoi,実数がかえってきてほしかったらatofです。
atoiやatofはエラーチェックがまったくできないので使ってはならない関数です。
strtolやstrtodを使うようにしましょう。
もし仮に、入力の整合性を別のところで保証できるなど、エラーチェックが必要ないということであれば、fscanfを使った方が簡単です。

ののき

Re: C言語 ファイル入出力

#8

投稿記事 by ののき » 8年前

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;
}

アバター
パコネコ
記事: 139
登録日時: 9年前
住所: 大阪

Re: C言語 ファイル入出力

#9

投稿記事 by パコネコ » 8年前

キャストを使わないなら素直に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言語 ファイル入出力

#10

投稿記事 by ののき » 8年前

パコネコ様のご指導通り、

コード:

 num=strtol(buf,80,fp); 
↓
 num=strtol(buf,NULL,10);
にしたところ、期待通りに動作いたしました。
かなり苦労していたので、嬉しい限りです。本当にありがとうございます。

閉鎖

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