掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.28154

複数行のテキスト入力
投稿者---ナトー(2006/09/14 16:17:02)


複数行のテキストを入力し検索文字列を入力した後、それらのテキスト行から検索文字列を探し、その検索文字列の出現回数をプリントするプログラムを書いているのですが、複数行のテキストの読み込みの段階でセグメンテーションフォルトになってしまいます。
*str[]というのがまずいのでしょうか?

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

#define MAXLINE 256 //最大256行
#define MAXLEN 256  //1行につき最大256文字

int main(void){
  int i, j,count=0;
  char *str[MAXLINE], search[MAXLEN];
  char *searchPtr;

  printf("テキストを入力してください\n"); //複数行のテキスト入力
  for(i=0;fgets(str[i],MAXLEN-1,stdin)!=EOF;i++){
    str[i][strlen(str[i])-1]='\0';
  }
  
  printf("検索文字列を入力してください\n");//検索文字列の入力
  fgets(search,MAXLEN-1,stdin);
  search[strlen(search)-1]='\0';
  
  printf("検索結果\n");

  for(j=0;j<i;j++){ //テキスト1行ごとに検索文字列を探す
    searchPtr=str[j];
    while((searchPtr=strstr(str[j],search))!=NULL){
count++;
      searchPtr++;
    }
  }
printf("出現回数は%d回\n",count);
  return 0;
}




この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:複数行のテキスト入力 28155 Blue 2006/09/14 16:58:57
<子記事> Re:複数行のテキスト入力 28156 nano 2006/09/14 17:28:18


No.28155

Re:複数行のテキスト入力
投稿者---Blue(2006/09/14 16:58:57)


下記の3つの違いを見てください。
あなたのコードは2番目のコードにあたります。
(よって、2番目のコードは実行できない)

  1. char text[ 1 ][ 256 ];
    strcpy( text[ 0 ], "test その1" );
    printf( "%s\n", text[ 0 ] );
    
  2. char* text[ 1 ];
    strcpy( text[ 0 ], "test その2" );
    printf( "%s\n", text[ 0 ] );
    
  3. char* text[ 1 ];
    text[ 0 ] = malloc( 256 );
    strcpy( text[ 0 ], "test その3" );
    printf( "%s\n", text[ 0 ] );
    free( text[ 0 ] );
    



この投稿にコメントする

削除パスワード

No.28156

Re:複数行のテキスト入力
投稿者---nano(2006/09/14 17:28:18)


fgets関数で1行あたり最大「MAXLEN-1」文字まで
読もうとしているのに、strの定義にMAXLENに関する
情報がないのはおかしい、という点にもお気づきください。



この投稿にコメントする

削除パスワード

No.28157

Re:複数行のテキスト入力
投稿者---nano(2006/09/14 17:32:54)


もう一点、fgets関数の戻り値をEOFと比べるのはダメです。


この投稿にコメントする

削除パスワード

No.28166

Re:複数行のテキスト入力
投稿者---ナトー(2006/09/15 13:40:22)


Blueさん、nanoさんアドバイスありがとうございます。
それを参考にして以下のように作り直してみました。すると複数行のテキスト入力はうまく行きました。しかしその次の検索文字列の入力部分のところから処理がおかしくなり、具体的には「検索文字列を入力してください」の後には標準入力から文字列を入力するようになるはずのところがいきなり「検索結果」が表示されてしまいます。その後の動作もきちんと動作していません。
searchの宣言部分に直接検索文字列を入れてやるときちんと動作するのですが、どこが間違っているのかよく分かりません。


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

#define MAXLINE 256 //最大256行
#define MAXLEN 256  //1行につき最大256文字

int main(void){
  int i, j, count=0;
  char str[MAXLINE][MAXLEN], search[MAXLEN];
  char *searchPtr;

  printf("テキストを入力してください\n"); //複数行のテキスト入力
  for(i=0;fgets(str[i],MAXLEN-1,stdin)!=NULL;i++){
    str[i][strlen(str[i])-1]='\0';
  }

  printf("検索文字列を入力してください\n");
  fgets(search,MAXLEN-1,stdin); //この2行が問題?
  search[strlen(search)-1]='\0';

  printf("検索結果\n");

  for(j=0;j<i;j++){ //テキスト1行ごとに検索文字列を探す
    searchPtr=str[j];
    while((searchPtr=strstr(searchPtr,search))!=NULL){
      count++;
      searchPtr++;
    }
  }

  printf("%sの出現回数は%d回\n",search,count);

  return 0;
}




この投稿にコメントする

削除パスワード

No.28167

Re:複数行のテキスト入力
投稿者---nano(2006/09/15 13:56:44)


実行環境について聞いていませんでしたので、教えてください。
最初の投稿で「セグメンテーションフォールト」と書かれていたので、
もしかするとUNIXですか?


この投稿にコメントする

削除パスワード

No.28168

Re:複数行のテキスト入力
投稿者---ナトー(2006/09/15 14:08:30)


>実行環境について聞いていませんでしたので、教えてください。
>最初の投稿で「セグメンテーションフォールト」と書かれていたので、
>もしかするとUNIXですか?

実行環境はFreeBSDです。


この投稿にコメントする

削除パスワード

No.28169

Re:複数行のテキスト入力
投稿者---nano(2006/09/15 14:12:06)


>実行環境はFreeBSDです。

検索対象のテキストと検索文字列とを
標準入力から入力する際の操作を
どのように行なわれているか、教えていただけますか?


この投稿にコメントする

削除パスワード

No.28172

Re:複数行のテキスト入力
投稿者---ナトー(2006/09/15 14:31:09)


>検索対象のテキストと検索文字列とを
>標準入力から入力する際の操作を
>どのように行なわれているか、教えていただけますか?

まずターミナルでプログラムを実行(./プログラム名)すると標準出力に
テキストを入力してください
と出てその次の行からテキストを入力します。例えば
hello(改行)
nice to meet you(改行)
good bye(改行)
とテキストを入力し、最後にctrl-dで終了します。
そして次に
検索文字列を入力してください
と出ます。この先は同じように検索文字列を入力(今度は1行だけ)し改行キーを押すと検索文字列の出現回数が出力されるはずですが、このプログラムでは検索文字列の入力が出来ないのです。


この投稿にコメントする

削除パスワード

No.28170

Re:複数行のテキスト入力
投稿者---123456789(2006/09/15 14:12:40)


おそらくですが、標準入力のバッファに入力が残っているのが問題かもしれません。
fgets(,,stdin)は標準出力から入力を持ってきますが、以前の入力がバッファに残っている場合、
こちらが入力する前にそれを取ってきてしまい、勝手に次に進んでしまう困った仕様があります。
つまり最初の

    for(i=0;fgets(str[i],MAXLEN-1,stdin)!=NULL;i++){
        str[i][strlen(str[i])-1]='\0';
      }

で入力した文字がMAXLEN-1より長かった場合、その超過分が

    fgets(search,MAXLEN-1,stdin); //この2行が問題?

で変数searchに入力されてしまい、こちらから入力することが出来ない現象がおきます。
これを回避するには、入力が長すぎた場合、バッファのクリアをします。
まあこれにも色々方法があるのですが、自分が良く使う手を書きます。

    int buf; /*   破棄用バッファ    */
    if ( (strchr(str, '\n')) == NULL ) {
        while ((buf = getchar()) != '\n' && buf != EOF);
    }

ようはstrに改行が無かった場合にバッファが残ってるとし、改行かEOFが出てくるまで
getcharで読み捨てるわけですね。
個人的にfflush?は信用ならんので使ってませんw
じゃあCtrl+M(winの場合はz)の時はどうするんだ、という質問はとりあえず却下。

ただし、もしかしたら全然違う原因かもしれないんので悪しからず



この投稿にコメントする

削除パスワード

No.28173

Re:複数行のテキスト入力
投稿者---ナトー(2006/09/15 14:46:10)


123456789さん、ありがとうございます。

一応入力するテキストはMAXLEN以上は入れてないですが何かバッファに残っているかもしれないと思ってputs(search)で確かめてみると何も入っていませんでした。


この投稿にコメントする

削除パスワード

No.28171

Re:複数行のテキスト入力
投稿者---shu(2006/09/15 14:17:35)


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

//
#define MAXLINE	256	//	最大256行
#define MAXLEN	256	//	1行につき最大256文字

//
int main(void)
{
    int i, j, count = 0;
    char str[MAXLINE][MAXLEN], search[MAXLEN];
    char *searchPtr;
    
    //	複数行のテキスト入力
    puts("テキストを入力してください");
    for (i = 0; i < MAXLINE && fgets(str[i], sizeof(str[i]), stdin) != NULL; i++) {
        //	不要	str[i][strlen(str[i])-1]='\0';
    }
    
    //	Ctrl+Z(Ctrl+D)...
    putchar('\n');
    
    //	検索文字列入力
    puts("検索文字列を入力してください");
    fgets(search, sizeof(search), stdin);	 //	このコメントの直前に全角空白がある。
    strtok(search, "\n");	//	search[strlen(search)-1]='\0';
    
    //	テキスト1行ごとに検索文字列を探す
    for (j = 0; j < i; j++) {
        searchPtr = str[j];
        while (strstr(searchPtr, search) != NULL) {
            count++;
            searchPtr++;	//	searchPtr += strlen(search);
        }
    }
    
    //	検索結果出力
    puts("検索結果");
    printf("%sの出現回数は%d回\n", search, count);
    
    return 0;
}


……検索文字列から入力した方がプログラムは簡単になる。


この投稿にコメントする

削除パスワード

No.28174

Re:複数行のテキスト入力
投稿者---ナトー(2006/09/15 14:58:41)


shuさんありがとうございます。

検索文字列の入力を先にすれば問題なく動作しました。


この投稿にコメントする

削除パスワード

No.28175

Re:複数行のテキスト入力
投稿者---shu(2006/09/15 15:23:57)


>検索文字列の入力を先にすれば問題なく動作しました。

動作云々は、全く関係無い。
上に書いたプログラムは、検索文字列の入力を先にするプログラムでもない。

検索文字列の入力を先にするプログラムにすれば、
str[MAXLINE][MAXLEN]なんて大きな領域は必要無くなる。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧