Segmentation fault

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
きなこ餅

Segmentation fault

#1

投稿記事 by きなこ餅 » 14年前

やりたいことは指定ディレクトリ以下の拡張子「.c .cpp .h」ファイルから
指定した文字列が出てくるファイル名と行数を取得し表示したいと思っています。

途中までファイルが全部表示されてしまい、最後にはSegmentation faultが出てしまいます。
どこがおかしいのか教えてください。

また、よろしければ、より効率よく実行できるような技術があれば助言していただけるとありがたいです。

よろしくお願いします。

開発環境
Mac OSX
gcc

コード:

#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>

int _search(char *, char *);

int main(int argc, char *argv[])
{
	char path[1024];
	char word[1024];
	int i;
	
	printf("\n\n"
		"************************************************\n"				
		"*		Word Search 〜Ver.1.0〜\n"
		"************************************************\n");
		
	if(argc <= 1)
	{
		strcpy(path,".");
	}
	else
	{
		for(i=1; i<argc; i++)
		{
			if(strcmp(argv[i],"-l") == 0)
			{
				if(strcmp(argv[i+1],"") != 0)
				{
					strcpy(path,argv[i+1]);
				}
				else
				{
					printf("Option ERROR!!\n");
					return 0;
				}
			}
			else if(strcmp(argv[i],"-w") == 0)
			{
				if(strcmp(argv[i+1],"") != 0)
				{
					strcpy(word,argv[i+1]);
				}
				else
				{
					printf("Option ERROR!!\n");
					return 0;
				}
			}
		}
	}
	
	if(strcmp(path,"") == 0)
	{
		strcpy(path,".");
	}

	_search(path,word);
	return 0;
}

int _search(char *path, char *word)
{
	struct stat st;
	struct dirent *dp;
	
	char *get_path;
	char *get_word;
	char *ex;
	char dir_file[1024];
	char next_dir[1024];
	char buf[1024];
	char check_buf[1024];
	char file_dir[1024];
	
	int i,x;
	
	mode_t m;
	FILE *fp;
	DIR *dir;

	get_path = path;
	get_word = word;
		
	dir = opendir(get_path);
	
	if(dir == NULL)
	{
		printf("Directory open ERROR!!\n");
		printf("%s",get_path);
		return 0;
	}
	
	for(dp=readdir(dir); dp!=NULL; dp=readdir(dir))
	{
		sprintf(dir_file,"%s",dp->d_name);
		
		stat(dir_file,&st);

		m = st.st_mode;
				
		if(S_ISREG(m))
		{
			ex = strstr(dir_file,".");
			
			if((strcmp(ex,".c") == 0) || (strcmp(ex,".cpp") == 0) || (strcmp(ex,".h") == 0))
			{
				sprintf(file_dir,"%s/%s",path,dir_file);
			
				fp = fopen(file_dir,"r");
				if(fp == NULL)
				{
					printf("File open ERROR!!\n");
					return 0;
				}
			
				x = 1;
				
				while((fgets(buf,1024,fp)) != NULL)
				{
					sprintf(check_buf,"%s",buf);
					
					if(strpbrk(check_buf,get_word) != NULL)
					{
						printf("%s : %d \"%s\"",file_dir,x,check_buf);
					}
					x++;
				}
			
				fclose(fp);			
			}
		}
		
		if(S_ISDIR(m))
		{
			if((strcmp(dir_file,".") != 0) && (strcmp(dir_file,"..") != 0))
			{
				sprintf(next_dir,"%s/%s",path,dir_file);
				
				_search(next_dir,get_word);
			}
		}
	}
	closedir(dir);
	
	printf("\n");

	return 0;
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: Segmentation fault

#2

投稿記事 by softya(ソフト屋) » 14年前

まず問題は、strpbrkだと単語ではなく一部の文字が一致するだけでNULLじゃ無くなってしまいます。
strstrとかを使われたほうが良いでしょう。
あとSegmentation faultはwindows上のcygwinでは再現されませんでした。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

きなこ餅

Re: Segmentation fault

#3

投稿記事 by きなこ餅 » 14年前

softya(ソフト屋) さんが書きました: あとSegmentation faultはwindows上のcygwinでは再現されませんでした。
環境に依存していると言うことでしょうか?

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: Segmentation fault

#4

投稿記事 by beatle » 14年前

gdbを使ってデバッグすると、原因の箇所はすぐに見つかるのではないかと思います。
ファイヤープロジェクト GDBが個人的に分かりやすい解説になっておりますので参考にしてください。
ブレークポイントを怪しそうな部分の直前に設定し、runするだけでもデバッガを使う価値があります。(一番最初は何もブレークポイントを設定せずにrunし、セグメンテーション違反が発生することを確認してください)
きなこ餅 さんが書きました:
softya(ソフト屋) さんが書きました: あとSegmentation faultはwindows上のcygwinでは再現されませんでした。
環境に依存していると言うことでしょうか?
もちろん環境に依存するでしょうね。そもそも実行する環境ごとにディレクトリに存在するファイルの数さえ違うのですから。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: Segmentation fault

#5

投稿記事 by h2so5 » 14年前

Mac OS X 10.7 64bit で実行してみましたが、
108行目でstrcmpにNULLポインタが渡された時点で落ちました。

strstrの戻り値をチェックする必要があります。

閉鎖

“C言語何でも質問掲示板” へ戻る