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

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

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

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

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

コマンド

コマンドとは特定のタスクを行う為に、コンピュータープログラムへ提示する指示文です。多くの場合、コマンドはShellやcmdようなコマンドラインインターフェイスに対する指示文を指します。

コマンドライン

コマンドライン(別名:Command Line Interface)は、ユーザに命令の入力を促す(プロンプト)文字列の表示を行い、すべての操作をキーボードを用いて文字列を打ち込む事でプログラムを走らせるユーザインターフェースです。

Q&A

解決済

3回答

2813閲覧

C言語、ファイル読み書き、コマンドライン引数、argc、argvについて

yatai

総合スコア4

C

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

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

コマンド

コマンドとは特定のタスクを行う為に、コンピュータープログラムへ提示する指示文です。多くの場合、コマンドはShellやcmdようなコマンドラインインターフェイスに対する指示文を指します。

コマンドライン

コマンドライン(別名:Command Line Interface)は、ユーザに命令の入力を促す(プロンプト)文字列の表示を行い、すべての操作をキーボードを用いて文字列を打ち込む事でプログラムを走らせるユーザインターフェースです。

0グッド

2クリップ

投稿2021/08/25 14:16

編集2021/09/01 08:34

input.txtを読み込み、計算結果をoutput.txtに書き出すプログラムを書いています

やりたいこと
・読み込み/書き出しのファイルを実行する時にargc,argvを用いて
コマンド行の引数で指定できるようにしたい
・引数の数のチェックをして足りないときはusageを表示して終了、
引数で受け取ったファイル名は別変数にコピーしてargvのまま用いないようにしたいです

補足
・読み込むファイル名は"input.txt"

txt

1//input.txt 21 32 43 54 65 76 87 98 109 1110

・書き出すファイル名は"output.txt"

txt

1//空

現在自分で書いたコードは以下です(8/31追記を元に修正しました)

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <math.h> 4#define N 10 5 6int main(int argc, char *argv[]) 7{ 8 int i,data[N]; 9 int sum = 0; 10 float ave = 0; 11 float sqave = 0; 12 float sd =0; 13 const char* file1 = "input.txt"; 14 const char* file2 = "output.txt"; 15 FILE *fp1,*fp2; 16 17//出力時の文字化けを直したい 18 19//引数で受け取ったファイル名は別変数にコピーしてargvのまま用いないようにしたい 20 file1 = argv[1]; 21 file2 = argv[2]; 22 23//引数の数のチェックをして足りないときはusageを表示して終了したい 24 if (argc < 3){ 25 printf("usage: %s in_file out_fileを用いてください\n", argv[0]); 26 return 1; 27 } 28 29//ファイルを開いて読み込み 30 if( (fp1=fopen(file1,"r")) == NULL){ 31 printf("%sファイルを開くことが出来ませんでした\n",file1); 32 return 1; 33 }else{ 34 printf("%sファイルをオープンしました\n",file1); 35 printf("%d 個の整数の合計を出力します\n", N); 36 } 37 38 for(i=0; i < N ; i++){ 39 fscanf(fp1,"%d\n", &data[i]); 40 printf("読み込みデータ = %d\n", data[i]); 41 sum += data[i]; 42 sqave += data[i]*data[i]; 43 } 44 fclose(fp1); 45 printf("%sファイルをクローズしました\n", file1); 46 47//計算部分 48 printf("%d 個の整数の平均と標準偏差を出力します\n", N); 49 ave = (float)sum/N; 50 sqave /= N; 51 sd = (sqave - ave*ave)*N/(N-1); 52 if(sd >= 0){ 53 printf("平均 = %.1f\n標準偏差 = %.1f\n", ave, sqrt(sd)); 54 }else{ 55 printf("平均 = %.1f\n標準偏差 = 存在しない値です\n", ave); 56 } 57 58//新規ファイルに書き出し 59 if( (fp2=fopen(file2,"w")) == NULL){ 60 printf("%sファイルを開くことが出来ませんでした\n",file2); 61 return 1; 62 }else{ 63 printf("%sファイルをオープンしました\n", file2); 64 fprintf(fp2,"平均 = %.1f\n標準偏差 = %.1f\n", ave, sqrt(sd)); 65 printf("平均と標準偏差を%sファイルに書き込みました\n", file2); 66 } 67 fclose(fp2); 68 printf("%sファイルをクローズしました\n", file2); 69 70 return 0; 71}

文字化けを直したいです。
よろしくお願いします。

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

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

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

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

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

hidezzz

2021/08/25 16:16 編集

「読み込み/書き出しのファイルを実行する時にargc,argvを用いてコマンド行の引数で指定できるようにしたい」の部分についてどのようにコマンド行に指定しようとしているのかがよくわかりませんでした。 具体的にどのようなコマンドラインを指定したのかを質問を修正して追記してみてください。 「コンパイル出来たものの、プログラムが動きませんでした。」の部分は、具体的には実行後にどのようになりますか?(実行しても何も表示されない、何らかのエラーメッセージが表示される、自分が意図していない計算結果が表示される、…など) こちらも質問に追記してみてください。 また正しい出力結果について想定されているものがあると思います。これについてもどういう出力結果になって欲しいのかを追記してみてください。
kazuma-s

2021/08/26 04:53

> ・変数の数のチェックをして足りないときはusageを表示して終了、 > 引数で受け取ったファイル名は別関数にコピーしてargvのまま用いないようにしたいです 変数というよりも、引数の数のチェックでは? 別関数ではなく、別変数にコピーでは?
yatai

2021/08/26 09:15

@hidezzzさん ありがとうございます。 >具体的にどのようなコマンドラインを指定したのかを質問を修正して 自分もよく分かっておらず、input.txtを扱いやすくするため?等、疑問です。 実行後の結果、想定される出力結果については後ほど追加します。
yatai

2021/08/26 09:17

@kazama-sさん ありがとうございます。 >変数というよりも、引数の数のチェックでは? >別関数ではなく、別変数にコピーでは? おっしゃる通りです。修正致します。 上記の解決策も教えていただけると幸いです。
guest

回答3

0

ベストアンサー

diff

1- int i,data[i]; 2+ int i, data[10]; 3 4- for(i=0; i < argc ; i++) 5+ for (i = 0; i < 10 ; i++) 6 7- data[i] = (int)argv[i];

この修正でとりあえず動くはずですが、
sd = (sqave - ave*ave)*10/(10-1); の意味が分かりません。
なぜ、10倍して 9で割っているのですか?

また、ファイル名が、input.txt と output.txt に固定で、
コマンドラインの引数で指定することができていません。

追記

・読み込み/書き出しのファイルを実行する時にargc,argvを用いて

C

1#include <stdio.h> 2 3int main(int argc, char *argv[]) 4{ 5 //・引数の数のチェックをして足りないときはusageを表示して終了、 6 if (argc < 3) { 7 printf("usage: %s in_file out_file\n", argv[0]); return 3; 8 } 9 10 // 引数で受け取ったファイル名は別変数にコピーしてargvのまま用いない 11 char *ifile = argv[1], *ofile = argv[2]; 12 13 FILE *fp1 = fopen(ifile, "r"); 14 if (fp1 == NULL) { printf("can't open %s\n", ifile); return 1; } 15 // データの読み込み 16 fclose(fp1); 17 18 // 計算 19 20 FILE *fp2 = fopen(ofile, "w"); 21 if (fp2 == NULL) { printf("can't create %s\n", ofile); return 2; } 22 // 計算結果の書き出し 23 fclose(fp2); 24 25 return 0; 26}

投稿2021/08/26 03:32

編集2021/08/30 15:08
kazuma-s

総合スコア8224

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

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

yatai

2021/08/26 08:46

ありがとうございます。 実行することが出来ましたが、文字化けしてしまいました。 対処方法はあるでしょうか?
yatai

2021/08/26 08:58

sd = (sqave - ave*ave)*10/(10-1); は10個の整数の不偏分散を表しています。 >また、ファイル名が、input.txt と output.txt に固定で、 コマンドラインの引数で指定することができていません。 学習途中ですみませんが、固定の際はコマンドラインの引数で指定が出来ないのでしょうか?
hidezzz

2021/08/26 10:01 編集

> 固定の際はコマンドラインの引数で指定が出来ないのでしょうか? ソースコード中に固定で指定しているのなら、コマンドライン引数で重複して指定する必要は無いです。 とりあえずは、ソースコードに埋め込まれたファイル名固定にするか、コマンドライン引数で指定するかのどちらかに仕様を決めたほうが良いと思います。 ちなみに、出来るか出来ないかという質問の直接の回答としては、やりようによっては出来る、となります。 (仕様の一例としては、コマンドライン引数で指定した場合はそちらを使用するが、指定しない場合はソースコード中の固定のファイル名を使うみたいな感じになるしょうか?) もしそのような仕様にするにしても、まずはプログラムとして正常な動作が出来るように仕上げるのが先かと思います。
yatai

2021/08/26 14:00

コマンドライン引数で指定する仕様にしたいです。 >(仕様の一例としては、コマンドライン引数で指定した場合はそちらを使用するが、指定しない場合はソースコード中の固定のファイル名を使うみたいな感じになるしょうか?) そのようなイメージにしたいと考えています。 まずは文字化けの原因を調べていますが、何が理由なのかいまいち分かりません、、。
hidezzz

2021/08/26 14:47

少なくとも、私は質問へのコメントに書いた質問の修正がされない限りこれ以上回答するつもりはありません。 他の方の回答を待つか、自力で頑張ってください。
yatai

2021/08/30 16:23

@kazuma-sさん 追記ありがとうございます。 自分で書いたコードのfile1,file2と追記のifile,ofileが共存できません といったエラーが出たので統一したのですが、上手くコンパイル出来ませんでした、、 また、argv[0] = 実行ファイル.exe となったのですが、この場合argv[1],argv[2]は どのように表記されるのでしょうか?
kazuma-s

2021/08/30 21:29

「自分で書いたコードのfile1,file2」とは何ですか? どうやって実行を開始していますか? コマンドライン引数に input.txt と output.txt を指定しましたか? コマンドラインが何か分かっていないのですか?
yatai

2021/08/31 09:10

すみません。追記していただいた物を元に質問を修正しました。 今の疑問点 ・最初に定義したfile1,file2と追記のifile,ofileをどのように統一すれば良いか ・コンパイルした際に文字化けするのはどうすれば直るか ・コマンドライン引数が何を指しているのか分からなくなってしまった という感じです。お答えいただけると幸いです。
kazuma-s

2021/08/31 10:32

文字化けもコマンドラインも環境に依存します。 どんなOS(Windows, Linux, MacOS など) で、どんなコンパイラ(VC++, gcc, ...)、 どんな IDE(Visual Studio, Eclipse, ...) で、文字コードの設定は何か、 どうやって実行を開始しているかなどを具体的に示してもらわないと回答できません。
yatai

2021/08/31 15:50

そうなのですね。無知ですみません。 Windows,gcc,mingw-w64,UTF-8で行っています。
kazuma-s

2021/09/01 03:29

minggw の gcc をつかっているということは端末はコマンドプロンプト(cmd.exe)で、 コマンドラインから > gcc -o hoge hoge.c > hoge input.txt output.txt のようにしてプログラムを起動しているのでしょうか? それとも端末は PowerShell ですか? Cygwin だったら端末は mintty かもしれませんが。 それで、コード中の、argc は 3、argv[0] = "hoge"、 argv[1] = "input.txt"、argv[2] = "output.txt" となりませんか? UTF-8 を使っているのなら、端末で chcp コマンドで確かめてください。 65001 なら UTF-8 ですが、932 なら Shift-JIS です。 ソースファイルは本当に UTF-8 ですか? どうやって確かめましたか? エディタは何ですか? メモ帳(notepad.exe)なら、名前を付けて保存を選ぶと文字コードが分かります。 ANSI なら Shift-JIS、Utf-8 ならそう表示されるはずです。
kazuma-s

2021/09/01 03:39

if (argc < 3) を if (argc != N) に変えたのはなぜですか? argc はコマンドライン引数の個数。N はファイル内のデータの個数 ということが分かっていないのですか?
yatai

2021/09/01 08:06

そこの理解も曖昧で、色々試してしまいました。 今回は「実行ファイル in_file out_file」の3つが引数と言うことでしょうか。 コマンドプロンプトで「実行ファイル in_file out_file」と入力することが分かったので printf("usage: %s in_file out_file\n", argv[0]);の意味が理解できたと思います。 上記を修正したところ、後は文字化けを直すだけになりました。 引き続き直したいと思います。
kazuma-s

2021/09/02 13:13

> 上記を修正したところ、後は文字化けを直すだけになりました。 本当ですか? 引数の argv[1]、argv[2] を参照した後、引数の個数 argc をチェックしても平気なのですか? 文字化けの問題は、最小限のプログラム printf("abcあいう123\n"); などを使用して、別の質問にしたほうが良いと思います。 文字化けは、様々な要素が絡み合って生じるので、どういう環境で、 どういう設定で実行しているのかを詳しく書かないと解決しないでしょう。
yatai

2021/09/02 13:28

>引数の argv[1]、argv[2] を参照した後、引数の個数 argc をチェックしても平気なのですか? そこの仕組みについては勉強途中なのですが、プログラムとしては動くようになりました。 また、文字化けに関して、 「gccによるコンパイルは、-fexec-charset=CP932 スイッチをつけてコンパイルする」 という操作で直すことが出来ました。 仕組みはよく分かっていないのですが、、
guest

0

Cのコードを組むなら、デバッグできる環境を整えましょう。
Windowsなら、VisualStudioなど。
コードの任意の場所で実行を止めることができ、変数の中身を見ることができます。
また、1行づつ実行して、変数の変化やコードの流れを見ることができます。

そうすれば自分の組んだコードがどう動くのかわからない、ってことはなくなるかと思います

投稿2021/08/25 14:24

y_waiwai

総合スコア87719

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

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

yatai

2021/08/26 03:50

ありがとうございます。 VisualStudioについて調べてみます。
guest

0

うろ覚えで申し訳ないですが、ファイル関連だけ。。。

//新規ファイルに書き出し //if( (fp2=fopen(file2,"w")) == NULL){ if( (fp2=fopen(file2,"wt")) == NULL){ //テキストモードでファイルを開く

もしくは

//新規ファイルに書き出し if( (fp2=fopen(file2,"w")) == NULL){  if( (fp2=fopen(file2,"wb")) == NULL){//バイナリモードでファイルを開くことを明記 printf("%sファイルを開くことが出来ませんでした\n",file2); return 1; }else{ printf("%sファイルをオープンしました\n", file2); //fprintf(fp2,"平均 = %.1f\n標準偏差 = %.1f\n", ave, sqrt(sd)); fprintf(fp2,"平均 = %.1f\r\n標準偏差 = %.1f\r\n", ave, sqrt(sd));//キャリッジリターンを追加 printf("平均と標準偏差を%sファイルに書き込みました\n", file2); }

で動きませんか?

投稿2021/09/02 13:07

kalen

総合スコア4

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

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

yatai

2021/09/02 13:29

ファイル関連は動くようになりました! ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問