![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
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. //と表示されます。
これは、どう対処したらいいのでしょうか?
調べてあれこれ対応してみたのですがどうにも対処できず困っています。
ぜひ教えていただけると助かります。
宜しくお願い致します。
No.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 オプションを付けて、警告をできる限り出して、一つ一つ潰していくことをお勧めします。
Kmee様
何度もアドバイスありがとうございます。
本日、無事コンパイルもとおり、ポインタから文字を取得することもでき、
また(おっしゃるとおりの)妙な構文も書きなおすことができました。
gcc -Wall
でのコンパイル、覚えます。
助かりました、ありがとうございました。
またわからないことがありましたらぜひ教えてください。
No.6
- 回答日時:
entry->d_nameの値は都度確認していますか?
デバッガなぞ使うまでもなくprintfで表示させるだけですが。
> ポインタ型に文字列は入らないです、すみません。
Cの「文字列」は即ち「文字型の配列」で、これはコードレベルでは「文字ポインタ型」と等価に扱えますから配列(の先頭アドレス)→ポインタは普通に代入できますけど?
> とりあえずデバックして他のところの中身を見たかったので
その姿勢が間違い。
型不一致系の警告は、「それは無視しても問題ない」としっかり検討した上でなければとんでもないバグの温床になります。
> コンパイルが通らないので
そこでは「何故コンパイルが通らないのか」を考えないと。
あと、コンパイルエラーを書かないと、ただ「通らない」というのがわかるだけの無価値な情報です。
D-Matsu様
無事コンパイルも通り、ポインタから文字を取得することができました。
デバッガを使うまでもなく、の意味がようやく今日わかりました。
ただ実行ファイル名を打てば、その場で表示されるのですね。
何度もアドバイスありがとうございました、大変助かりました。
また疑問がありましたらぜひ教えてください。
No.5
- 回答日時:
コンパイルオプション-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でデバックをしています(つまずいていますが・・・)
とにかく、ひとつ進んですっきりしました。
大変助かりました、ありがとうございました。
No.4
- 回答日時:
> 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を全て素通りしてしまいます。
どうにかしてファイル名を文字列で取得したいのですが、どうしたらいいでしょうか。
もし何かご存知でしたら教えてください。
どうぞ宜しくお願い致します。
No.3
- 回答日時:
もう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構造体なのでしょうか)、半角英数の羅列でところどころファイル名とあっている部分がある表記が入っています。
サブディレクトリ名やファイル名を文字列として取得するにはどうしたらいいのでしょうか。
もし何かアドバイスいただけると大変助かります。
どうぞ宜しくお願い致します。
No.1
- 回答日時:
>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日かけてもうまくいかず困っています。
もし何かご存知でしたらぜひ教えてください。
どうぞ宜しくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) サブフォルダ(データ)にある複数の.xlsxファイルのSheet3のA2セルの値で01から左側をB2 2 2022/08/14 15:46
- C言語・C++・C# const char** p;のとき、free(p)でC4090エラーとなるのはなぜですか 3 2023/03/31 16:28
- Visual Basic(VBA) VBA GetAttrについて教えてください 2 2022/12/22 15:25
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# c言語 コマンドライン引数 4 2023/02/09 18:47
- その他(プログラミング・Web制作) VScodeでpythonプログラムの関数を実行したい 2 2022/07/13 19:24
- Visual Basic(VBA) VBAでの共有パスにつきまして 1 2023/03/04 17:24
- Visual Basic(VBA) 集めたシートのシート名を変更したい。 下記のコードでサブフォルダにあるファイルのSheet3を集めて 6 2022/08/23 10:38
- C言語・C++・C# スタックフレームの消滅 6 2023/05/20 12:33
- JavaScript [再掲]指定したパスが現URLに含まれていたら特定要素を削除するJavascriptのコードについて 1 2023/05/10 15:09
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
クイックソートの比較交換回数...
-
セグメントエラー
-
init関数の意味
-
C言語のポインタに直接アドレス...
-
プーさんのマウスポインタを教...
-
ポインタのミスでOS壊れるの...
-
参照型で受け取った引数をポイ...
-
Win32 APIウィンドウプロシージ...
-
関数ポインタの高速化のメリット
-
どうしてエラーになるかわかり...
-
C言語の勉強しています。すみま...
-
C++におけるポインタの使い方
-
C言語 ポインタと配列の違い...
-
C言語によるリスト構造について...
-
ポインタと画像なのですが…
-
C言語のコンパイルと実行ファイ...
-
基本アルゴリズムの『返す』の...
-
型のバイト数はビルド時に全部...
-
[C言語] NULLは必ず0(番地)です...
-
DelphiでCreateProcessがうまく...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
fopne で失敗する原因
-
init関数の意味
-
Run-Time Check Failure #3とい...
-
戻り値で構造体を返すことは可...
-
LPSTR型の初期化について
-
Cで作成したDLL関数をVBから呼...
-
ExcelVBAでのkernel32(64bit)
-
アプリを32bitから64bit移行
-
構造体とfscanf
-
c言語で任意のファイルから読み...
-
デバイスハンドルとは?
-
main(int argc,char **argv[])...
-
基本アルゴリズムの『返す』の...
-
コンストラクタでnewを失敗した...
-
C言語の関数と配列に関する質問
-
ハンドル、アドレス、ポインタ...
-
参照型で受け取った引数をポイ...
-
DLL<->VB間での受け渡し(文字...
おすすめ情報