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

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

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

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

Q&A

解決済

2回答

675閲覧

コマンドライン引数の取り扱いについて

ken21

総合スコア17

C

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

0グッド

1クリップ

投稿2020/11/02 04:34

編集2020/11/02 05:09

表題の件、次のことを実現したいのでご協力ください。

最終的に実現したいこと。
コマンドライン引数より ファイルオープン分類(数字) ファイル形式 ファイル名を入力しfopen関数の引数として
利用する。

今回実現したいこと
fopen関数の第2引数である、オープンモードの文字列をコマンドライン引数の「ファイルオープン分類」、「ファイル形式」から作成する関数を作りたいと思っています。作成するにあたって以下が諸条件です。

条件
・main関数とは分離する
・ファイルオープン分類として入力する数値とオープンモードの対応は以下の通り
1:r, 2:w, 3:a, 4:r+, 5:w+

・ファイル形式は以下の通り
c:テキスト,b:バイナリ
→ファイル形式を指定しているのはbが選択された場合に対応するためです。

困っている個所
以下のようにコードを書いていますが、実行するとファイルダンプが発生します。
どのように変更すればopenModeStrにオープンモードの文字列を格納し、表示させることが出来るでしょうか。

#include<stdio.h> #include<string.h> int makeModeStr(char openMode, char fileType, char *openModeStr); int main(int argc, char *argv[]) { char openModeStr[4]; int check = makeModeStr(argv[1][0], argv[2][0], openModeStr); printf("openModeStr = %s\n", openModeStr); return 0; } int makeModeStr(char openMode, char fileType, char *openModeStr){ if (openMode == '1') { strcpy(openModeStr, "r"); } else if (openMode == '2') { strcpy(openModeStr, "w"); } else if (openMode == '3') { strcpy(openModeStr, "a"); } else if (openMode == '4') { strcpy(openModeStr, "r+"); } else { strcpy(openModeStr, "w+"); } if (fileType == 'b') { strcat(openModeStr, "b"); } return 0; }

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

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

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

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

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

guest

回答2

0

ベストアンサー

openModeはchar型なので、char型の値と比較して下さい。

C

1// if (openMode == "1") { 2if (openMode == '1') {

投稿2020/11/02 04:38

編集2020/11/02 04:39
LouiS0616

総合スコア35668

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

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

ken21

2020/11/02 05:12

回答ありがとうございます。 比較の個所はそれで問題なくなりました。 ※コードは修正しました。 しかし、実行後にファイルダンプが発生します。 何か致命的な個所がありますでしょうか? 何か
LouiS0616

2020/11/02 05:16

コマンドライン引数はどのように渡していますか?
ken21

2020/11/02 05:34

すいません、コマンドライン引数を exe 数字 でしか渡していませんでした。 exe 数字 ファイルタイプで入力したら問題なく実行できました。 ありがとうございました。 最後に2点だけ確認させてください。 今回のような関数呼び出しをすると変数openModeとfileTypeにはargvが持っているアドレスが格納されていると思います。(printfを使って確認したらopenとfileの変数にはアドレスが入っていました) makeModeStr(argv[1][0], argv[2][0], openModeStr); int makeModeStr(char openMode, char fileType, char *openModeStr) その場合だとしての疑問ですが、、 ①なぜif文で文字と比較ができたのでしょうか。 (下の書き方だとアドレスと文字の比較になってエラーが起きる気がします) ②仮引数側にアドレスが入っていたのは呼び出した際に仮引数がポインタ変数にキャストされている? if (openMode == '1')
LouiS0616

2020/11/02 05:37 編集

> 変数openModeとfileTypeにはargvが持っているアドレスが格納されていると思います。 いいえ。 argv[i] は i番目のコマンドライン引数(もっと正確に言えば、i番目のコマンドライン引数の先頭アドレス)であり、argv[i][0] はその0文字目です。 > なぜif文で文字と比較ができたのでしょうか。 openModeが文字だからです。アドレスでは無いです。
ken21

2020/11/02 05:44

なるほど文字を渡しているでよかったのですね。 ただ、下記のように記入した場合※にargv[1][0]とopenModeの出力が同じなのが気になりました。 この結果をもってopenModeへアドレスが渡ったと判断したのですが何か根本的に考え方が間違ってますでしょうか? int main(int argc, char *argv[]) { printf("argv[1][0] = %p\n", argv[1][0]); printf("argv[2][0] = %p\n", argv[2][0]); char openModeStr[4]; int check = makeModeStr(argv[1][0], argv[2][0], openModeStr); printf("openModeStr = %s\n", openModeStr); return 0; } int makeModeStr(char openMode, char fileType, char *openModeStr){ printf("openMode = %p", openMode); printf("fileType = %p", fileType);
LouiS0616

2020/11/02 05:45

%pで出力できることは、アドレスが渡っていることの証左にはなりません。 %dでも%cでも出力できる筈です。
LouiS0616

2020/11/02 05:47

ところで、コンパイルの際に警告が出るように設定しているでしょうか。 かなりの潜在バグを検知できます。
ken21

2020/11/02 05:50

cygwinを使っていますが警告などの設定をどのようにするかはわかっておりません。 コンパイルする際はそのような設定をしたほうが良いのでしょうか。
LouiS0616

2020/11/02 05:53

cygwinは実行環境ですよね? コンパイラは何をお使いですか。gccとかclangとかclとかです。
ken21

2020/11/02 06:01

gccです。 cygwinがコンパイラだと思っておりました、、、
LouiS0616

2020/11/02 06:06

gcc -Wall -Wextra プログラム.c でコンパイルしてみて下さい。
ken21

2020/11/02 07:00

コンパイルしてみました。 利用してないcheckの変数やprintf(%p= ....,openMode)の個所でエラー表示が出ました。 %pの個所は「format argument is not a pointer (arg 2)」と出たのでその変数がポインター、つまりアドレスを持っていないということですね?
LouiS0616

2020/11/02 07:07

%pで出力されるべきではない、って意味ですね。 > その変数がポインター、つまりアドレスを持っていないということですね? アドレスを持っていないというとちょっと語弊がありますが、 当該変数が直接保持している値がアドレスではない(=変数がポインタではない)のはそうです。
ken21

2020/11/02 07:13

なるほど。このような調べ方もあるんですね。 大変勉強になりました。
guest

0

コマンドラインで入力した数字、ファイル形式の文字をchar型の仮引数へ渡したいのですが

やりたいことが間違っています。charには1文字しか入れられませんので、複数文字が来うる文字列の受け渡しには使えません。

投稿2020/11/02 04:36

編集2020/11/02 04:43
maisumakun

総合スコア146018

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

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

LouiS0616

2020/11/02 04:39

複数文字は引き渡さない前提で良いように見えます。 > ファイルオープン分類として入力する数値とオープンモードの対応は以下の通り 1:r, 2:w, 3:a, 4:r+, 5:w+ > ファイル形式は以下の通り c:テキスト,b:バイナリ
maisumakun

2020/11/02 04:43

あっ、ほんとだ。
ken21

2020/11/02 05:13

はい、argv[1][0]のように指定して一文字で渡そうと考えております。 ※この記述で文字が渡せるかはわからないですが、、、
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問