プロが教える店舗&オフィスのセキュリティ対策術

こんにちは。

セグメンテーションエラーが出て困っています。下のプログラムは、strstrによるテキストファイルからの文字列の検索と抽出を目的としたものです。具体的には文字列「00:18:52.491692」を含んだ行を見つけたいと考えています。
何かお気づきの点等ありましたら是非ご教授頂きたく思います。

#include<stdio.h>
#include<string.h>

int main(){

FILE *fp;

if( (fp = fopen("file.txt","r")) == NULL){
printf("fopen:error\n");
exit(-1);
}

char *answer;
char target[1024] = "00:18:52.491692";
char source[1024];
while( (fgets(source,1024,fp)) != NULL){
answer = strstr(source,target);
if(answer != NULL){
printf("%s\n",answer);
break;
}
}
fclose(fp);
return 0;
}


以下がファイルの中身です。
00:18:52.486843 IP (tos 0x10, ttl 64, id 56604, offset 0, flags [DF], proto: TCP (6), length: 100) 10.1.4.12.ssh > 10.1.4.99.49964: P 1724257568:1724257616(48) ack 648002683 win 718 <nop,nop,timestamp 2123242756 28297809>

00:18:52.491692 IP (tos 0x10, ttl 64, id 56605, offset 0, flags [DF], proto: TCP (6), length: 164) 10.1.4.12.ssh > 10.1.4.99.49964: P 48:160(112) ack 1 win 718 <nop,nop,timestamp 2123242756 28297809>

00:18:52.486957 IP (tos 0x10, ttl 64, id 31393, offset 0, flags [DF], proto: TCP (6), length: 52) 10.1.4.99.49964 > 10.1.4.12.ssh: ., cksum 0xce39 (correct), 1:1(0) ack 48 win 501 <nop,nop,timestamp 28297832 2123242756>

00:18:52.486985 IP (tos 0x10, ttl 64, id 31394, offset 0, flags [DF], proto: TCP (6), length: 52) 10.1.4.99.49964 > 10.1.4.12.ssh: ., cksum 0xcdc9 (correct), 1:1(0) ack 160 win 501 <nop,nop,timestamp 28297832 2123242756>

00:18:52.487816 IP (tos 0x0, ttl 64, id 7429, offset 0, flags [DF], proto: UDP (17), length: 68) 10.1.4.12.32986 > 10.1.4.1.domain: [bad udp cksum 7869!] 63212+ PTR? 99.4.1.10.in-addr.arpa. (40)


どんな些細な意見でもいいので、皆さんのお力を貸して頂けないでしょうか。どうぞよろしくお願いします。

A 回答 (5件)

拙者宅では、stdlib.hをインクルードするだけで、動きましたけよ。


# exit()を使用するには、stdlib.hが必要なのに、ないからコンパイルエラーになりましたよ。

ただ、疑わしい個所があるので、念のため修正しておきました。
----------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>  // 追加
#include <string.h>

int main(){

  FILE *fp;

  if( (fp = fopen("file.txt","r")) == NULL){
    printf("fopen:error\n");
    exit(-1);
    return -1;
  }

  char *answer;
  char target[1024] = "00:18:52.491692";
  char source[1024];
  char printbuffer[1024];// 追加
  while( (fgets(source,1024,fp)) != NULL){
    answer = strstr(source,target);
    if(answer != NULL){
      strcpy(printbuffer, answer);// 追加
      printf("%s\n", printbuffer);// 変更
      break;
    }
  }
  fclose(fp);
  
  return 0;
}
----------------------------------------------------------------------
strstr()の戻り値を、直接printf()に渡してよいかどうかは、疑問。
    • good
    • 0
この回答へのお礼

stdlibファイルは単にこのサイトにコピペするのを忘れておりました。混乱を招きましたこと深くお詫び申し上げます。

お騒がせしております本プログラムですが、時間を置いてまた実行してみますと結果はすんなり実行出来ました。しかし、何が原因だったのかは全くもって不明のままです。
たまにこういう事が私の環境ではあるようで、コンパイルして出来たa.outを実行しても、「前にコンパイルして出来た」a.outを実行してしまう事が何度かありました。つまり、既存のa.outファイルが正常に上書きされない事があるようなんです。これに気づいた場合は-oオプションで出力名を変える事で解決しているのですが・・、一体なんでしょうね、この現象は。

最後になりますが、Yanchさんを始めとする皆さんのご回答、及び御高察に深く感謝いたします。有難う御座いました。

お礼日時:2008/11/09 16:52

プログラム実行しましたがエラー出ませんねぇ・・・



コンパイル時も stdlib.h だけでしたし。
これないと exit が使えないはずです。
まさか筆問者の環境がexit未定義のエラーを出さずにビルドしてしまって、
file.txt がなくて exit(1) が実行されて・・・とかあるのでしょうか?


補足:セグメンテーションエラー(セグメンテーション違反)について
http://ja.wikipedia.org/wiki/%E3%82%BB%E3%82%B0% …

書き込みできないメモリに書き込もうとすると出るエラーのようです。
    • good
    • 0

#1/#2両氏のように動かした訳ではないですが、見た限りでもコード自体には問題がないように見えます。


#インクルード忘れは置いておくとして

とりあえず環境(OS、コンパイラ)は明示しましょう。
あとはステップ実行等で「どこで、何が」エラー原因になっているかを突き止めておくとエラー解析がやりやすいです。

> #3
> answer = ("00:18:52.491692" を含む行の内容);

より正確にというか一般的な書き方をすると
answer = ("00:18:52.491692" を含む行の、"00:18:52.491692"以降);
ですね。
strstr()は検索文字列がヒットした場合、ヒット位置のアドレスを返しますから。
今回はたまたま行頭な訳ですが、ってこれならstrncmp()でいいような気がしますねぇ。
    • good
    • 0

>answer = "00:18:52.491692";



あ、正確には、
answer = ("00:18:52.491692" を含む行の内容);
ってことです。
    • good
    • 0

>#1さん


> strstr()の戻り値を、直接printf()に渡してよいかどうかは、疑問。

全く問題ありません。
strstr() の戻り値は単なる char *型で、詰まるところ
answer = "00:18:52.491692";
としたのと同じことですから。

あ、ちなみに、うちの環境(Borland C++とg++)でもちゃんと動きました。
    • good
    • 0

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