COMとユーザの対話型しりとりプログラムでの動作停止問題

このQ&Aのポイント
  • COMとユーザの対話型しりとりプログラムで実行すると動作が停止する問題が発生しています。
  • 問題は「しり文字と一致する単語を辞書ファイルから探す関数」の内部にあることが分かっています。
  • 辞書ファイルはひらがなの日本語辞書であり、関数の実装がややこしくなっています。
回答を見る
  • ベストアンサー

COMとユーザの対話型しりとりプログラムです。

COMとユーザの対話型しりとりプログラムです。 コンパイルエラーは出ないのですが、実行すると動作が停止します。 問題は「しり文字と一致する単語(すべて日本語です)を辞書ファイル(txtファイル)から探す関数」 内にあることが分かっています。 ------関数部分のみ------- void Com_String(char *shiri_word){ char *p; if((fpd=fopen(FILENAME,"r"))==NULL)puts("FILE OPEN ERROR"); while(fscanf(fpd,"%s",com_input_buf)!=EOF){ p=strstr(com_input_buf,shiri_word); if(strcmp(p,com_input_buf)==0){break;} else{p=NULL;} } fclose(fpd); } -------終--------- 日本語のひらがな辞書ファイルなので、ややこしいことになってしまいました。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

どこで「動作が停止」していてそのときに変数の値がどうなっているのかをデバッガを使って確認しましたか? ・fopen()に失敗したとき、"FILE OPEN ERROR"の文字を出力した後にwhileループを実行してしまいます ・strstr()で文字列が見つからなかったとき、pの値はNULLになります。その状態でstrcmp()を実行すると...

g_pumpkin
質問者

お礼

ありがとうございました。 以下のように修正するとうまくいきました。 ------修正後------ void Com_String(char *shiri_word) { char *p=NULL; if((fpd=fopen(FILENAME,"r"))==NULL){ puts("FILE OPEN ERROR"); exit(0); } while(fscanf(fpd,"%s",com_input_buf)!=EOF){ p=strstr(com_input_buf,shiri_word); if(p==NULL){p='\0';} else if(strcmp(p,com_input_buf)==0){break;} } fclose(fpd); } ----------------------- デバッガですが、もしよろければ使い方を教えて貰えますか。 調べてみたのですが、うまくいかないです。 コンパイラはgcc です。 gcc -g a.c で実行ファイルを作って、 gdb a 'gdb'は内部コマンドまたは外部コマンド、 操作可能なプログラムまたはバッチファイルとして認識されていません。 と出てしまいます。

関連するQ&A

  • プログラムが止まってしまいます

    Visual Studio 2012 c++ でプログラムを動かそうと思っているのですが、デバッグ開始すると画像のようなウィンドウが出て実行途中で止まってしまいます。 呼び出し履歴のint mqoLoadFileのソースを貼ります. int mqoLoadFile( MQO_OBJECT *mqoobj, char *filename, double scale, unsigned char alpha) { FILE *fp; MQO_OBJDATA obj[MAX_OBJECT]; MQO_MATDATA *M = NULL; char buf[SIZE_STR]; // 文字列読み込みバッファ char path_dir[SIZE_STR]; // ディレクトリのパス char path_tex[SIZE_STR]; // テクスチャファイルのパス char path_alp[SIZE_STR]; // アルファテクスチャファイルのパス int n_mat = 0; // マテリアル数 int n_obj = 0; // オブジェクト数 int i; // MaterialとObjectの読み込み fopen_s(&fp,filename,"rb"); if (fp==NULL) return 0; mqoobj->alpha = alpha; memset(obj,0,sizeof(obj)); i = 0; while ( !feof(fp) ) { fgets(buf,SIZE_STR,fp); // Material if (strstr(buf,"Material")) { sscanf_s(buf,"Material %d", &n_mat); M = (MQO_MATDATA*) calloc( n_mat, sizeof(MQO_MATDATA) ); mqoReadMaterial(fp,M); } // Object if (strstr(buf,"Object")) { sscanf_s(buf,"Object %s", obj[i].objname);//ココの実行中に止まる mqoReadObject(fp, &obj[i]); i++; } } n_obj = i; fclose(fp);

  • CSVを用いた検索プログラム動かし方

    #pragma warning( disable: 4996 ) #include <stdio.h> #include <string.h> #include <fstream> using namespace std; typedef struct tagKOTOWAZA{ char japanese[50]; char english[50]; }KOTOWAZA; int main() { char buf[256]; KOTOWAZA c[200]; int i, count; /*ifstream strtok strcpy を使ってファイルを読み込む*/ //=====ここから===== ifstream fin("Book1.csv"); if(fin.is_open()){ //ファイル内容の表示とクローズ for(count=0;fin.getline(buf, sizeof(buf)), !fin.eof();count++){//読み込める間 //printf("%s",buf);デバッグ用 char *p; p = strtok(buf,","); if(p)strcpy(c[count].japanese,p); p = strtok(NULL,","); if(p)strcpy(c[count].english,p); } fin.close(); }else{ printf("ファイルのオープンに失敗しました。\n"); return 1; } //=====ここまで==== return 0; } ここからどうすればCSVファイルに書いた 漢字,English を検索できるのかがわかりません・・・ 言語はC++を使っていますvisualstudio2012を使っています。 どうすればいいのか全く分かりません。 よろしくお願いします。

  • ファイル

    ファイルを読み込み単語ごとに表示するプログラムです。 例 ファイル データ 形式 歴史・・ のように単語の後には空白がありますファイルです FILE *fp; char buf[1000]; char buf_word[1000]; char *str; char *bufstr; if((fp = fopen("test.txt","r")) == NULL){ printf("error!"); return 0; } while(fgets(buf,1000,fp) !=NULL){ str = buf; while(*str !='\0'){ strbuf = buf_word; if(*str ==' '){ printf("%s",buf_word); } else{ *strbuf++ = *str++; } } } とプログラムしてみましたが*strの値がどうもおかしく 最初が "フ" じゃなく"・"になってます。 最初の単語がG11とかなら"G"になっていますが・・ 教えて下さい。

  • このプログラムは

    どこかおかしいですか? int main(void){ FILE *str; char buf[1000]; if((fp=fopen("ファイル名","r"))=NULL){ printf("ファイルが開けません"); return EXIT_SUCCESS; } while(fgets(buf,1000,fp) !=NULL){ str=buf; printf("%s",buf); } return EXIT_SUCCESS; } で実行すると前半4割程度が表示されません。 何故だかわかる人いませんか? 使用言語:C言語 環境:visualC++6.0 のコンソールアプリケーション。

  • プログラム

    以前ファイルからXとYの値だけ取り出し図形を作る質問をした者ですが void Ctest::OnOK() { FILE *fp; char *str,buf[1000];     char buf3[100],*s3; char buf4[100],*s4; if ((fp = fopen("test.txt", "r")) == NULL) { printf("ファイルが開けません\n"); return EXIT_SUCCESS; } while (fgets(buf, 1000, fp) != NULL) { str=buf;        while((*str!='\0'){ if(*str!='\0' && *str=='X'){ *str++; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) s3=buf3; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) while(*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) *s3++=*str++; *s3='\0'; } if(*str!='\0' && *str=='Y'){ *str++; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) s4=buf4; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) while(*str!='\0' &&(isdigit(*str) |*str=='||*str=='.')) *s4++=*str++; *s4='\0'; CDC *v; GetDC(); MoveTo(0,0); LineTo(atof(buf3),atof(buf4)); ReleaseDC(v); } else str++; } } fclose(fp); return 0; } でコンパイルはできるのですが直線の作図がされません。 どこが間違ってるのでしょうか。VC+6.0のMFC使ってます

  • C の文字列置き換え

    #include <stdio.h> // buffer overflowは無視している文字列置き換え関数 void replace(char *buf, char *pre, char *aft) {   char *p;   p = strstr(buf, pre);   if (p){     char *p_2 = p + strlen(pre);     replace(p_2, pre, aft);     memmove(p + strlen(aft), p_2, strlen(p_2)+1);     memcpy(p, aft, strlen(aft));   } } int main(void) {   char buf[1024] = "C:\\programfile\\LOG";   replace(buf, "LOG", "RESULT");   printf("%s\n", buf);   return 0; } というソースが以前出ていたのですがこのバッファーオーバフローはどうすれば回避できるのですか? お願いします

  • C言語に関する質問

    初めて質問させて頂きます。C言語初心者です。 実は講義で「ファイル中の英文を単語に分けてその出現頻度をカウントするコードを木構造を用いて出力せよ」という課題が出ました。 そこで、参考にするコードを検索しましたところ、以下のURLにあるベストアンサーのコードが近いと感じました。 http://okwave.jp/qa/q4155655.html コードの内容は以下の通りになります。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> typedef struct node Node; struct node{ char *word; int count; Node *left,*right; }; Node *root=NULL; void compose(FILE *fp); void inorder(Node *p); void strlower(char *s); int main(int argc, char *argv[]) { FILE *fp; Node *new; fp=fopen(argv[1],"r"); if(fp==NULL){puts("ファイルを開けません");return(-1);} compose(fp); inorder(root); return (0); } void strlower(char *s){ while(*s!=NULL){*s=tolower(*s);s++;} } void compose(FILE*fp){ Node **p,*new; char buf[256]; while(1){ fscanf(fp,"%[^a-zA-Z0-9]",buf); if(fscanf(fp,"%[a-zA-Z0-9]",buf)==EOF)break; strlower(buf); if(root==NULL){ new=(Node *)malloc(sizeof(Node)); new->left=NULL; new->right=NULL; new->word=strdup(buf); new->count=1; root=new; }else{ *p=root; while(1){ if(strcmp(buf,(*p)->word)==0){ (*p)->count++;break; }else if(strcmp(buf,(*p)->word)<0){ if((*p)->left==NULL){ new=(Node *)malloc(sizeof(Node)); new->left=NULL;new->right=NULL;new->word=strdup(buf);new->count=1; (*p)->left=new; break; }else{ *p=(*p)->left; } }else{ if((*p)->right==NULL){ new=(Node *)malloc(sizeof(Node)); new->left=NULL; new->right=NULL; new->word=strdup(buf); new->count=1; (*p)->right=new; break; }else{ *p=(*p)->right; } } } } } } void inorder(Node*p){ if (p==NULL) return; inorder(p->left); printf("%s %d\n",p->word, p->count); inorder(p->right); } しかし、これをそのままコンパイル・実行すると、コンパイル時に以下の注意が出ます。 warning comparison between pointer and integer ('int' and 'char *') while(*s!=NULL){*s=tolower(*s);s++;} 上記の注意を無視してそのまま実行すると、segmatation faultが出てしまいますorz おそらく、sの型が*s=s[]なので、注意の中の「s++」の部分で誤作動を起こしている(s++を実行するにはsはint型でなければならない)と思うのですが、どうコード文を変えれば良いのかがよくわかりません。 どなたかお教え頂けると幸いです。どうぞよろしくお願いしますm(_ _)m

  • 文字列を引数にしたがって置換するプログラムを作りました。

    文字列を引数にしたがって置換するプログラムを作りました。 test.txtを新規作成、abcdefghijklmnopqrstuvwxyz を書き込みセーブ 引数 : abc=zz mnopq=u - 出力結果 - zzdefghijklurstuvwxyz というような結果になるプログラムを作ったのですが、これをstr系とmem系の関数を使わずにポインタを使って組みなおしたいと思うのですが、全くわからないので質問させて頂きました。 よろしくお願いします。 質問下手なので質問でダメな点があれば随時補足していきたいと思います。 #include"stdafx.h" #include<stdio.h> #include<string.h> #include<stdlib.h> #define BUF 128 #define MOJI 128 #define MAX 128 #pragma warning(disable : 4996) using namespace System; int main(int argc, char *argv[]) { FILE *fp; char txt[BUF]; char hiki_mae[MAX][MOJI]; char hiki_ato[MAX][MOJI]; int i = 0, n = 0, j = 0; int hiki_num = 0; char txt_mae[BUF], txt_ato[BUF]; char *p; char sagyou_txt[BUF], sagyou_argv[MAX][MOJI]; if(argc < 2){ printf("argc = %d >>> パラメータ不足です\n", argc); exit(1); } if( (fp = fopen("test.txt", "r")) == NULL ){ printf("ファイルがオープンできません\n"); exit(1); } for(i = 1; i < argc; i++){ if( strchr(argv[i], '=') != NULL && strlen(argv[i]) > 2){ strcpy(sagyou_argv[hiki_num],argv[i]); p = strstr(sagyou_argv[hiki_num],"="); *p = '\0'; strcpy(hiki_mae[hiki_num], sagyou_argv[hiki_num]); strcpy(hiki_ato[hiki_num], sagyou_argv[hiki_num] + strlen(hiki_mae[hiki_num]) + 1); hiki_num++; } } while( fgets(txt, BUF, fp) != NULL){ printf("変換前>%s\n",txt); } for(n = 0; n < hiki_num; n++){ while( strstr(txt, hiki_mae[n]) != NULL ){ strcpy(sagyou_txt, txt); p = strstr(sagyou_txt, hiki_mae[n]); *p = '\0'; strcpy(txt_mae, sagyou_txt); strcpy(txt_ato, sagyou_txt + strlen(txt_mae) + strlen(hiki_mae[n])); strcat(txt_mae, hiki_ato[n]); strcat(txt_mae, txt_ato); strcpy(txt, txt_mae); } } printf("変換後>%s\n",txt); fclose(fp); return 0; }

  • 二分探索木への挿入

    今学校で二分探索木を勉強しています。二分探索木に要素を挿入したいのですが、うまくいかないのでアドバイスをいただけないでしょうか。ファイル中の英文を単語に分けてその出現頻度をカウントするプログラムです。とりあえず二分探索木を作るところまではなんとか完成させたいです。 #include <stdio.h> #include <stdlib.h> #include<string.h> #include <ctype.h> typedef struct node Node; struct node{ char *word; int count; Node *left,*right; }; Node *root=NULL; Node *compose(FILE *fp); void inorder(Node *p); int main(int argc, char *argv[]) { FILE *fp; Node *new; fp=fopen(argv[1],"r"); if(fp==NULL){ puts("ファイルを開けません"); return(-1); } new=(Node *)malloc(sizeof(Node *)); new=compose(fp); inorder(new); return (0); } Node *compose(FILE *fp) { Node **p,*new; char buf[20]; p=&root; while(fscanf(fp,"%[-a-z-A-Z0-9_]",buf)!=EOF){ while(*p!=NULL){ (*p)->count=0;  /*countを0で初期化したいけどwhileの外にこの1行を出すとエラーが出る*/ buf[0]=tolower(buf[0]); strdup(buf); if(strcasecmp(buf,(*p)->word)==0){   /*if文にしかはいらない…*/ (*p)->count++; printf("%d\n",(*p)->count); }else if(strcasecmp(buf,(*p)->word)<0){ p=&(*p)->left; }else{ p=&(*p)->right; } } new=(Node *)malloc(sizeof(Node *)); new->left=NULL; new->right=NULL; new->word=buf; *p=new; fscanf(fp,"%*[^-a-z-A-Z0-9_]"); } return(new); } void inorder(Node *p) { if(p==NULL) return; printf("%s",p->word); if(p->count!=0){ printf("%d",p->count); } inorder(p->right); inorder(p->left); }

  • プログラム

    { FILE *fp; char *str,buf[1000];   char subbuf[100],*s1; char buf2[100],*s2;   char buf3[100],*s3; char buf4[100],*s4; static double bx=0; static double by=0; if ((fp = fopen("test.txt", "r")) == NULL) { printf("ファイルが開けません\n"); return EXIT_SUCCESS; } while (fgets(buf, 1000, fp) != NULL) { str=buf;        while((*str!='\0'){ if(*str!='\0' && *str=='G'){ *str++; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) s2=buf2; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) while(*str!='\0'&&(isdigit(*str) || *str=='-' || *str=='.')) *s2++=*str++; *s2='\0'; } if(*str!='\0' && *str=='X'){ *str++; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) s3=buf3; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) while(*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) *s3++=*str++; *s3='\0'; } if(*str!='\0' && *str=='Y'){ *str++; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) s4=buf4; if((*str!='\0' &&(isdigit(*str) || *str=='-' || *str=='.')) while(*str!='\0' &&(isdigit(*str) |*str=='||*str=='.')) *s4++=*str++; *s4='\0'; } CDC *v; v=GetDC(); if((int)atof(buf2)==92){ MoveTo((int)atof(buf3),(int)atof(buf4)); bx=(int)atof(buf3); by=(int)atof(buf4); ReleaseDC(v); } else if((int)atof(buf2)==01){ MoveTo((int)bx,(int)by); LineTo((int)atof(buf3),(int)atof(buf4)); bx=(int)atof(buf3); by=(int)atof(buf4); ReleaseDC(v); } else str++; } } fclose(fp); return 0; } という風なプログラムになっているのですが 今現在 G01X30Y30 G01X30Y120というファイルをこのプログラムにて実行すると (0,0)→(30,30)→(30,120)というような直線が引かれます。 しかしこれを G01X30Y30 Y120 とかかれたときも同様の結果がでるようにしたいです。 つまり最初のG○○が省略されているときは前回のGの値を X○○が省略されているときは前回のXの値を使うように 変更したいのですがどのように変更すればいいのかがわかりません。 教えてください。