質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

2023閲覧

求めた素数をテキストファイルにおきたい

ain4425

総合スコア19

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2016/10/09 14:55

1~50000までの素数を出して、それをテキストファイルに並べて書き込みたいのですが、うまく移せません。今回移す先は、34.txtとしています。また、2が素数として出されるコードが書けないので、そのところも教えていただけると幸いです。以上よろしくお願いいたします。

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <math.h> 4FILE *filepointer; 5char filename[5000]; 6int n; 7void Sosuu(); 8 9int main(){ 10 sprintf( filename,"34.txt"); 11 Sosuu(); 12 fclose(filepointer); 13 return 0; 14 } 15 16void Sosuu(){ 17 int y,x,i; 18 for(n=2; n<50001; n++) 19 { 20 y=0; 21 22 for(i=2; i<n; i++){ 23 x=n%i; 24 if(x==0){ 25 break; 26 } 27 if( i == (n-1) ){ 28 y++; 29 break; 30 } 31 } 32 33 if(y!=0){ 34 35 36 if( NULL == (filepointer=fopen(filename,"w"))) 37 { 38 printf("\n %s cannot be opened \n",filename); 39 exit(1); 40 } 41 fprintf(filepointer,"%d\n",n); 42 43 44 } 45 } 46} 47

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

こんにちは。

素数が見つかる度にファイルをオープンし、そのまま次の素数を探し、見つかったらまたファイルをオープンしてますね。そのうちファイルを開ける上限(私のところでは510個でした)に到達し、オープンに失敗して終わっています。
Sosuu()関数から返ってきたところでfclose()してますので、対応が分かりやすいようSosuu()関数の呼び出し前にファイルをオープンした方が良いです。

2が素数として出されるコードが書けない

y(フラグ)の使い方をちょっと工夫すればできますよ。今は「2~n-1の間に割り切れる除数があったら素数」としているから2が外れてしまいます。n=2の時2を割り切れる数はありませんから。
「2~n-1の間に割り切れる除数があったら素数でない」とすれば良いです。

投稿2016/10/09 15:49

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ain4425

2016/10/09 16:30

ご回答ありがとうございます。ファイルを開ける上限があるのですか、、。いままで知らずにやっていました。私の感覚として、ファイルは開きっぱなしいうよりは、毎回開いて閉じるものだと解釈しておりましたので、「最初に開いておく」のが鉄板であることは新鮮に感じられます。いわれてみればそのほうがシンプルで分かりやすいですね。 フラグの使い方、今回の2を含めさせる考え方、もう一度考え直してみます。ありがとうございました。
Chironian

2016/10/10 02:38

毎回開いて閉じる使い方もありますが、遅くなるので特に理由がない限りあまりしないです。 それと、開いた後閉じてないですよ。
guest

0

ベストアンサー

「何故これがグローバル変数?」という物ばかりですが、それはさて置くと、
fopenする部分をループの外、例えば、mainsosuu()呼び出し直前に移動させると、3以降の素数は書けます。
「ファイルオープンとは何か」「ファイルクローズとは何か」を学ばれると良いでしょう。

また、2が素数として出されるコードが書けないので、そのところも教えていただけると幸いです。

今まで見た素数を求めるプログラムは、「エラトステネスのふるい」を使わない単純なものの場合、奇数だけを探索範囲にして、2を特別扱いする物ばかりでした。

このプログラムを出来るだけ変えないで修正すると、

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <math.h> 4FILE *filepointer; 5char filename[5000]; 6int n; 7void Sosuu(); 8 9int main(){ 10 sprintf( filename,"34.txt"); 11 if( NULL == (filepointer=fopen(filename,"w"))) 12 { 13 printf("\n %s cannot be opened \n",filename); 14 exit(1); 15 } 16 Sosuu(); 17 fclose(filepointer); 18 return 0; 19 } 20 21void Sosuu(){ 22 int y,x,i; 23 for(n=2; n<50001; n++) 24 { 25 y=1; 26 27 for(i=2; i<n; i++){ 28 x=n%i; 29 if(x==0){ 30 y=0; 31 break; 32 } 33 if( i == (n-1) ){ /*ここからの3行は無意味だが*/ 34 break; 35 } 36 } 37 38 if(y!=0){ 39 fprintf(filepointer,"%d\n",n); 40 } 41 } 42}

元のプログラムで2が出ないのは、n=2の時にはfor(i=2; i<n; i++){のループが一度も実行されないためです。

投稿2016/10/09 15:36

otn

総合スコア84499

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ain4425

2016/10/09 16:21

何を学べばよいのか等、為になるようなご回答ありがとうございました。訂正してくださった通り、yの設定が甘かったのが一番の大きなミスでした。また、無意味な行についても納得できました、ありがとうございます。ただ、ひとつお聞きしたいことがあります。 グローバル変数をなくそうと思いましたが、「FILE *filepointer;」の部分だけがどうしても取り除くことができません。main関数とSosuu関数の始まりにそれぞれ「FILE *filepointer;」を宣言しましたが、プログラムの応答が返ってきません。 「FILE *filepointer;」というのは、ファイルについてどこまで行ったかを示すあだ名の設定だと解釈していました。main関数とSosuu関数のそれぞれの始めに定義すれば動くと思ったのですが、なぜ応答しないのでしょうか。ご教授いただけると幸いです
otn

2016/10/09 16:33 編集

> なぜ応答しないのでしょうか。 それぞれの関数でそれぞれローカル変数として宣言すると、同名であっても別の変数として扱われます。 一案としては、mainで宣言して、sosuuには引数で渡します。名前は同じでも良いし、下記のように変えてもかまいません。 main(){ FILE *filepointer; ~~ sosuu(filepointer); ~~ } void sosuu(FILE *fp){ ~~ fprintf(fp,"%d\n",n); ~~ } 別案としては、mainではファイルは触らず、sosuuの先頭でオープンして、sosuuの最後でクローズする。
ain4425

2016/10/09 16:39

ありがとうございます、理解しました!なにか自分は[FILE *filepointer]を特別な呪文か何かだと思っていました。intやfloatなどの型にあたる部分がFILEであるので、普通の変数のように関数間で引数として受け渡せるんですね。自分なりに納得できました。このたびはありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問