dポイントプレゼントキャンペーン実施中!

Cで人が書いたプログラムを修正しています。
IDEではなくLinux環境でのコード修正が初めてで、デバックでのバグ潰しや実行ファイル生成がうまく行かず困ってます。
warningをきちんと治したいというのと、gdbの起動がうまくいかない、という2点です。

あるディレクトリに保存された、ABCという文字を含んだサブディレクトリに対して処理を行うプログラムです。
まず1つめ、warningの修正について教えてください。

test=opendir(buff); //DIR変数ポインタ  *test にパスを代入して、
//そのパスにABCという文字が含まれていたら以下を実行、というところ
if(test==NULL&&errno!=){
check=strchr(test,"ABC"); //checkはchar型ポインタです。ここでincomparableな変数だというwarningが出ます。

DIRポインタで取得したパス名をstrchrで比較することはできないのでしょうか。char変数mojiを追加しcheckもchar型に変更して
 moji = test
 check=strchr(moji,"ABC")
としてみましたがNGでした。

このwarningは単に警告なのでとりあえず実行ファイルを作ってデバックしてみたら、と言われ a.outファイルを生成しました。デバッカgdbを起動したところで、2つ目の疑問が発生しました。

gdb 対象ファイル名.c
(gdb) break main   //と打つと、ここで
No symbol table is loaded. Use the "file" command.  //と表示されます。
これは、どう対処したらいいのでしょうか?

調べてあれこれ対応してみたのですがどうにも対処できず困っています。
ぜひ教えていただけると助かります。
宜しくお願い致します。

A 回答 (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 オプションを付けて、警告をできる限り出して、一つ一つ潰していくことをお勧めします。
    • good
    • 0
この回答へのお礼

Kmee様

何度もアドバイスありがとうございます。
本日、無事コンパイルもとおり、ポインタから文字を取得することもでき、
また(おっしゃるとおりの)妙な構文も書きなおすことができました。
gcc -Wall
でのコンパイル、覚えます。
助かりました、ありがとうございました。
またわからないことがありましたらぜひ教えてください。

お礼日時:2010/12/15 21:12

entry->d_nameの値は都度確認していますか?


デバッガなぞ使うまでもなくprintfで表示させるだけですが。

> ポインタ型に文字列は入らないです、すみません。

Cの「文字列」は即ち「文字型の配列」で、これはコードレベルでは「文字ポインタ型」と等価に扱えますから配列(の先頭アドレス)→ポインタは普通に代入できますけど?

> とりあえずデバックして他のところの中身を見たかったので

その姿勢が間違い。
型不一致系の警告は、「それは無視しても問題ない」としっかり検討した上でなければとんでもないバグの温床になります。

> コンパイルが通らないので

そこでは「何故コンパイルが通らないのか」を考えないと。
あと、コンパイルエラーを書かないと、ただ「通らない」というのがわかるだけの無価値な情報です。
    • good
    • 0
この回答へのお礼

D-Matsu様

無事コンパイルも通り、ポインタから文字を取得することができました。
デバッガを使うまでもなく、の意味がようやく今日わかりました。
ただ実行ファイル名を打てば、その場で表示されるのですね。
何度もアドバイスありがとうございました、大変助かりました。
また疑問がありましたらぜひ教えてください。

お礼日時:2010/12/15 21:09

コンパイルオプション-gはつけていますか?-gを付けないとデバッグシンボルが


実行ファイル内に埋め込まれません。
例えば以下のように指定します。
例)gcc 対象ファイル名.c -g
Makefileを使っている場合は、CFLAGSあたりを調べて-gを追記してください。


もし、コンパイル時に最適化オプション(-O、-O1、-O2など)を指定していたら、それも
外してください。
正しくステップ実行できなくなりますので。


もし、Makefile内でstripを行っていた場合、その行を無効化してください。
stripでデバッグシンボルが削除されてしまいますので。


以上はgdb a.outでデバッグできなかったときのアドバイスです。
    • good
    • 0
この回答へのお礼

jkk65536様

すぐにご記入くださってありがとうございます。
ご指摘を踏まえ、

gcc -g -o0 対象ファイル名.c

としたところ無事コンパイルできました。
a.outが生成され、現在はgdbでデバックをしています(つまずいていますが・・・)
とにかく、ひとつ進んですっきりしました。
大変助かりました、ありがとうございました。

お礼日時:2010/12/15 05:15

> DIRポインタで取得したパス名をstrchrで比較することはできないのでしょうか。



そもそも「文字列の比較」を行うのならstrcmp()を使いますし、test内に"ABC"があるかどうかを探すのならstrstr()を使います。
選ぶ関数が間違い。
strchr()のプロトタイプはchar *strchr(const char *, char)なので第二引数に「文字列」は使えません。

というか……

> このwarningは単に警告なのでとりあえず実行ファイルを作ってデバックしてみたら

「警告」は確かに無視できるものですが、無視すると場合によりひどい目にあうものでもあります。
教える側がこんなことを言うようでは……
    • good
    • 0
この回答へのお礼

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を全て素通りしてしまいます。
どうにかしてファイル名を文字列で取得したいのですが、どうしたらいいでしょうか。
もし何かご存知でしたら教えてください。
どうぞ宜しくお願い致します。

お礼日時:2010/12/15 05:25

もう1点


opendirは、ファイル用のfopenにあたる操作です。
fopen後、freadやfget等の読むための操作が必要なように、 readdirが必要です。
testが示すアドレスから文字列(DIR構造体ではない)と解釈して、そこに"ABC"が含まれている可能性は0ではありませんが、それは、サブディレクトリの名前ではありません。
    • good
    • 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構造体なのでしょうか)、半角英数の羅列でところどころファイル名とあっている部分がある表記が入っています。
サブディレクトリ名やファイル名を文字列として取得するにはどうしたらいいのでしょうか。
もし何かアドバイスいただけると大変助かります。
どうぞ宜しくお願い致します。

お礼日時:2010/12/15 05:25

gdbで指定するのは実行ファイルです。


ソースファイルではありません。

書籍や解説サイトがあるので一読しておくことをお勧めします。


前半部分は、プログラムのロジック、C言語の文法、標準関数の使い方の問題です。
IDEを使う使わないに関係ありません。
    • good
    • 0
この回答へのお礼

kmee様

すみません、基本的に間違えていました。
gdbではa.outを指定するのですね。
解読サイトを読んでやり直しました。
ご指摘ありがとうございました。

お礼日時:2010/12/15 05:26

>if(test==NULL&&errno!=){



errno と、何を比べてますか?
また、test が NULLであるときに

>check=strchr(test,"ABC"); //checkはchar型ポインタです。

ここを通る可能性がありますが、本当にいいんですか?

さらにさらに、strchrの第2引数の型が間違ってます。
ていうか、使う関数そのものが間違ってます。
"ABC"を含んでいるかどうかを調べるときに使うのは、「strstr」関数です。
仕様をよ~く調べてください。
    • good
    • 0
この回答へのお礼

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日かけてもうまくいかず困っています。
もし何かご存知でしたらぜひ教えてください。
どうぞ宜しくお願い致します。

お礼日時:2010/12/15 05:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!