- ベストアンサー
C言語のコンパイルと実行ファイル作成の困りごと
- Cで人が書いたプログラムを修正する際に、Linux環境でのコード修正が初めてで困っています。主な問題はwarningの修正とgdbの起動です。
- warningの修正については、DIRポインタで取得したパス名をstrchrで比較することができないことが原因です。修正方法として、char型変数を追加し、パス名をその変数に代入し、その後にstrchrを使用するようにしましょう。
- gdbの起動に関しては、No symbol table is loaded. Use the 'file' command.と表示されるエラーが発生しています。このエラーは、symbol tableがロードされていないことが原因です。解決方法として、gdbコマンド内で'file'コマンドを使用して対象ファイルを指定しましょう。
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
対処法がまるで逆になってます。 IDEとかLinuxとかデバッガとかそんなの関係ありません。 strstrがエラーになるのなら、そのエラーの原因を探るのが本筋でしょう。 それを、まったく目的の違うstrchrを使ったって上手く動作するはずがありません。 例えるなら、「printfで表示が乱れたので、scanfにしたら、まったく表示されなくなりました」ってくらい、おかしな対処法です。 他にも > sprintf(buff, "%s%s\\",dirpath,entry->d_name); bufの型は?初期化とか領域確保とかしてますか? それが出来てたら > if(buff!=NULL){ こんなタイミングでNULLチェックするのはあきらかに変です。 このsprintfではbuff自体の値は変わりません。 > check=strchr(entry->d_name,"ABC"); これをstrstrに変えたとして > if(checkabc!=NULL){ ・・・ 使ってる変数はcheckなんですか?checkabcなんですか? エラーになったのはこの変数の間違いとかないですか? エラーメッセージが無いので判断できません。 他にもおかしなところがあるような気がします。 gcc に -Wall オプションを付けて、警告をできる限り出して、一つ一つ潰していくことをお勧めします。
その他の回答 (6)
- D-Matsu
- ベストアンサー率45% (1080/2394)
entry->d_nameの値は都度確認していますか? デバッガなぞ使うまでもなくprintfで表示させるだけですが。 > ポインタ型に文字列は入らないです、すみません。 Cの「文字列」は即ち「文字型の配列」で、これはコードレベルでは「文字ポインタ型」と等価に扱えますから配列(の先頭アドレス)→ポインタは普通に代入できますけど? > とりあえずデバックして他のところの中身を見たかったので その姿勢が間違い。 型不一致系の警告は、「それは無視しても問題ない」としっかり検討した上でなければとんでもないバグの温床になります。 > コンパイルが通らないので そこでは「何故コンパイルが通らないのか」を考えないと。 あと、コンパイルエラーを書かないと、ただ「通らない」というのがわかるだけの無価値な情報です。
お礼
D-Matsu様 無事コンパイルも通り、ポインタから文字を取得することができました。 デバッガを使うまでもなく、の意味がようやく今日わかりました。 ただ実行ファイル名を打てば、その場で表示されるのですね。 何度もアドバイスありがとうございました、大変助かりました。 また疑問がありましたらぜひ教えてください。
- jjk65536
- ベストアンサー率59% (66/111)
コンパイルオプション-gはつけていますか?-gを付けないとデバッグシンボルが 実行ファイル内に埋め込まれません。 例えば以下のように指定します。 例)gcc 対象ファイル名.c -g Makefileを使っている場合は、CFLAGSあたりを調べて-gを追記してください。 もし、コンパイル時に最適化オプション(-O、-O1、-O2など)を指定していたら、それも 外してください。 正しくステップ実行できなくなりますので。 もし、Makefile内でstripを行っていた場合、その行を無効化してください。 stripでデバッグシンボルが削除されてしまいますので。 以上はgdb a.outでデバッグできなかったときのアドバイスです。
お礼
jkk65536様 すぐにご記入くださってありがとうございます。 ご指摘を踏まえ、 gcc -g -o0 対象ファイル名.c としたところ無事コンパイルできました。 a.outが生成され、現在はgdbでデバックをしています(つまずいていますが・・・) とにかく、ひとつ進んですっきりしました。 大変助かりました、ありがとうございました。
- D-Matsu
- ベストアンサー率45% (1080/2394)
> DIRポインタで取得したパス名をstrchrで比較することはできないのでしょうか。 そもそも「文字列の比較」を行うのならstrcmp()を使いますし、test内に"ABC"があるかどうかを探すのならstrstr()を使います。 選ぶ関数が間違い。 strchr()のプロトタイプはchar *strchr(const char *, char)なので第二引数に「文字列」は使えません。 というか…… > このwarningは単に警告なのでとりあえず実行ファイルを作ってデバックしてみたら 「警告」は確かに無視できるものですが、無視すると場合によりひどい目にあうものでもあります。 教える側がこんなことを言うようでは……
お礼
D-Matsu様 アドバイスありがとうございました! 現在のコートは dir=opendir(dirpath); while(NULL!=(entry=readdir(dir))){ //これでディレクトリ内の複数のファイルを全てチェックしているつもり。 sprintf(buff, "%s%s\\",dirpath,entry->d_name); testabc=entry->d_name; //testabcはcharポインタ型。ファイル名をtestabcに代入しているつもり。 if(buff!=NULL){ check=strchr(entry->d_name,"ABC"); //checkはcharポインタ型。本当はstrstr(testabc,"ABC")としたいが、コンパイルが通らないのでstrchrにしました。ポインタ型に文字列は入らないです、すみません。ですがとりあえずデバックして他のところの中身を見たかったのでこうしてしまいました。 if(checkabc!=NULL){ ・・・ としているのですが、checkには0*0(つまり値なし?)となってしまいます。 対象ディレクトリには全6つのファイルがあり、4つ目のファイル名にABCが含まれますが、このcheckを全て素通りしてしまいます。 どうにかしてファイル名を文字列で取得したいのですが、どうしたらいいでしょうか。 もし何かご存知でしたら教えてください。 どうぞ宜しくお願い致します。
- kmee
- ベストアンサー率55% (1857/3366)
もう1点 opendirは、ファイル用のfopenにあたる操作です。 fopen後、freadやfget等の読むための操作が必要なように、 readdirが必要です。 testが示すアドレスから文字列(DIR構造体ではない)と解釈して、そこに"ABC"が含まれている可能性は0ではありませんが、それは、サブディレクトリの名前ではありません。
お礼
kmee様 いつもアドバイスありがとうございます! 会社で作業しているためすぐに書き込みできず申し訳ありません。 現在のコードは dir=opendir(dirpath); while(NULL!=(entry=readdir(dir))){ //これでディレクトリ内の複数のファイルを全てチェックしているつもり。 sprintf(buff, "%s%s\\",dirpath,entry->d_name); testabc=entry->d_name; //testabcはcharポインタ型。ファイル名をtestabcに代入しているつもり。 if(buff!=NULL){ check=strchr(entry->d_name,"ABC"); //checkはcharポインタ型。本当はstrstr(testabc,"ABC")としたいが、コンパイルが通らないのでstrchrにしました。ポインタ型に文字列は入らないです、すみません。ですがとりあえずデバックして他のところの中身を見たかったのでこうしてしまいました。 if(checkabc!=NULL){ ・・・ としています、ご指摘のとおりtestabcの中身をデバックして確認すると(これがDIR構造体なのでしょうか)、半角英数の羅列でところどころファイル名とあっている部分がある表記が入っています。 サブディレクトリ名やファイル名を文字列として取得するにはどうしたらいいのでしょうか。 もし何かアドバイスいただけると大変助かります。 どうぞ宜しくお願い致します。
- kmee
- ベストアンサー率55% (1857/3366)
gdbで指定するのは実行ファイルです。 ソースファイルではありません。 書籍や解説サイトがあるので一読しておくことをお勧めします。 前半部分は、プログラムのロジック、C言語の文法、標準関数の使い方の問題です。 IDEを使う使わないに関係ありません。
お礼
kmee様 すみません、基本的に間違えていました。 gdbではa.outを指定するのですね。 解読サイトを読んでやり直しました。 ご指摘ありがとうございました。
- asuncion
- ベストアンサー率33% (2127/6289)
>if(test==NULL&&errno!=){ errno と、何を比べてますか? また、test が NULLであるときに >check=strchr(test,"ABC"); //checkはchar型ポインタです。 ここを通る可能性がありますが、本当にいいんですか? さらにさらに、strchrの第2引数の型が間違ってます。 ていうか、使う関数そのものが間違ってます。 "ABC"を含んでいるかどうかを調べるときに使うのは、「strstr」関数です。 仕様をよ~く調べてください。
お礼
asuncion様 アドバイスありがとうございました。 ご指摘のerrnoには、前行でerrno=0と代入済みでした、記載せずすみません。 現在のコードは以下のとおりです。 dir=opendir(dirpath); while(NULL!=(entry=readdir(dir))){ //これでディレクトリ内の複数のファイルを全てチェックしているつもり。 sprintf(buff, "%s%s\\",dirpath,entry->d_name); testabc=entry->d_name; //testabcはcharポインタ型。ファイル名をtestabcに代入しているつもり。 if(buff!=NULL){ check=strchr(entry->d_name,"ABC"); //checkはcharポインタ型。本当はstrstr(testabc,"ABC")としたいが、コンパイルが通らないのでstrchrにしました。ポインタ型に文字列は入らないです、すみません。ですがとりあえずデバックして他のところの中身を見たかったのでこうしてしまいました。 if(checkabc!=NULL){ ・・・ 該当ディレクトリにある4つ目のファイル名にABCが含まれるにも関わらず、checkには0*0しか入らずにプログラムが終了してしまい、困っています。 ファイル名を文字列として取得するにはどうしたらいいのでしょうか。 周りに聞いたりサイトを調べてあれこれやってみているのですが、2日かけてもうまくいかず困っています。 もし何かご存知でしたらぜひ教えてください。 どうぞ宜しくお願い致します。
お礼
Kmee様 何度もアドバイスありがとうございます。 本日、無事コンパイルもとおり、ポインタから文字を取得することもでき、 また(おっしゃるとおりの)妙な構文も書きなおすことができました。 gcc -Wall でのコンパイル、覚えます。 助かりました、ありがとうございました。 またわからないことがありましたらぜひ教えてください。