• 締切済み

このプログラムは「こんにちは」と打つと「こんにちは、元気ですか」と返答

このプログラムは「こんにちは」と打つと「こんにちは、元気ですか」と返答するプログラムです このプログラムを改良して「こんにちは」と打つと「こんにちは、元気ですか」と言うようなキーワードを打つ決められた回答をするようなものを増やしていきたいのですが、どのように改良すればよいでしょうか? 例えば 「寒いですね」といれると「冬だからね」となるように #include <stdio.h> #include <string.h> int reply(const char *s) { const char *reply_s[] = {"こんにちは 元気ですか?", "バイバイ", "ふ~ん?"}; if(strstr(s, "こんにちは")) puts(reply_s[0]); else if(strstr(s, "さようなら")){ puts(reply_s[1]); return 0; } else puts(reply_s[2]); return 1; } int main(void) { char s[128]; do{ char *p; fgets(s, sizeof s, stdin); if(p = strchr(s, '\n')) *p = '\0'; }while(reply(s)); return 0; }

みんなの回答

  • chie65535
  • ベストアンサー率43% (8525/19379)
回答No.2

「人工無能」とか「人工痴能」とかでネット検索すると、質問にあるような「学習型簡易自動応答プログラム」についての情報やソースコードを見付ける事が出来ます。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

私だったら、こんな風にします。 1)質問の文字列とそれに対応する答えの文字列を   メンバーとする構造体を定義する。 2)上記構造体の配列を定義する。   例:   配列[0]:{ "こんにちは", "こんにちは 元気ですか?" }   配列[1]:{ "寒いですね", "冬だからね" }   配列[2]:{ "バイバイ", "さようなら" } 3)プログラム本体では、入力した文字列をキーとして   上記構造体配列の質問部分を検索する。 4)検索にヒットすれば、その質問に対応する答えの部分を   出力する。

関連するQ&A

  • 再帰プログラム

    #include<stdio.h> int rstrlen(char*); int main(void) { char str[100]; printf("文字列を入力してください\n"); gets(str); printf("文字数は %d です\n",rstrlen(str)); return 0; } int rstrlen(char *p) { if(*p){ p++; return 1+rstrlen(p); } else return 0; } 文字数を計算するプログラムです。 if(*p)の*pとはNULLを表しているのですか?

  • プログラムについて

    今スタっクのファイルから読み込んだ文字列をスタっクへプっシュしたりポっプしたりする過程がわかるプログラムを作ってます 。 作りかけのプログラムですがどこをどうすればいいか教えてください!! 一応コンパイルできます。 使ってない関数があるかもしれません。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define NUMBER 100 /*--- スタックを実現する構造体 ---*/ typedef struct { int max; /* スタックのサイズ */ int ptr; /* スタックポインタ */ char *stk; /* スタック(の先頭要素へのポインタ) */ } Stack; /*--- スタックの初期化 ---*/ int StackAlloc(Stack *s, int max) { s->ptr = 0; if ((s->stk = calloc(max, sizeof(int))) == NULL) { s->max = 0; /* 配列の確保に失敗 */ return (-1); } s->max = max; return (0); } /*--- スタックの後始末 ---*/ void StackFree(Stack *s) { if (s->stk != NULL) { free(s->stk); s->max = s->ptr = 0; } } /*--- スタックにデータをプッシュ ---*/ int StackPush(Stack *s, int x, int i,char *a[]) { if (s->ptr >= s->max) return (-1); if(x>=i) { puts("プッシュできる文字データはありません。"); return (-1); } strcpy(&s->stk[s->ptr++],&(*a)[x]); x++; return x; } /*--- スタックからデータをポップ ---*/ int StackPop(Stack *s, int x,char *a[]) { if (s->ptr <= 0) /* スタックは空 */ return (-1); strcpy(&s->stk[--s->ptr],&(*a)[x]); return (0); } /*--- スタックからデータをピーク ---*/ int StackPeek(const Stack *s, int *x) { if (s->ptr <= 0) /* スタックは空 */ return (-1); *x = s->stk[s->ptr - 1]; return (0); } /*--- スタックの大きさ ---*/ int StackSize(const Stack *s) { return (s->max); } /*--- スタックに積まれているデータ数 ---*/ int StackNo(const Stack *s) { return (s->ptr); } /*--- スタックは空か ---*/ int StackIsEmpty(const Stack *s) { return (s->ptr <= 0); } /*--- スタックは満杯か ---*/ int StackIsFull(const Stack *s) { return (s->ptr >= s->max); } /*--- スタックを空にする ---*/ void StackClear(Stack *s) { s->ptr = 0; } int main(void) { int i=0,j,ret,x=0; char *a[NUMBER]; char buffer[20]; FILE *fpin; Stack s; fpin=fopen("input2.txt","r"); //テキストファイルを読み取りモードで開く while(fgets(&buffer[0],sizeof(buffer),fpin) !=NULL ) { if(i>=NUMBER)//読み込む人数がNUMBERを超えてる時の処理 { puts("人数が100人を超えています"); goto END; } strcpy(&a[i][0],&buffer[0]); /*ret=sscanf(&buffer[0],"%s",&a[i][0]); //データ文字列を3分割 if(ret!=1) //1に分割できなかったときの処理 { puts("代入された入力項目の個数が3でありません"); goto END; }*/ i++; } for(j=0; j<i; j++) printf("%s\n",&(*a)[j]); if (StackAlloc(&s, 100) == -1) { puts("スタックの確保に失敗しました。"); return (1); } while (1) { int m; printf("現在のデータ数:%d/%d\n", StackNo(&s), StackSize(&s)); printf("(1) プッシュ (2) ポップ (0) 終了:"); scanf("%d", &m); if (m == 0) break; switch (m) { case 1: printf("データ:"); puts("こんちくしょ~"); if(StackPush(&s, x,i,&(*a)) == -1) puts("スタックへのプッシュに失敗しました。"); break; case 2: if(StackPop(&s, x,&(*a)) == -1) puts("ポップできません。"); else printf("ポップしたデータは%sです。\n", &s.stk[s.ptr]); break; } } StackFree(&s); END: fclose(fpin); return (0); }

  • c言語関数の(1)~(5)までの部分が何をやっているのかよく分からない

    c言語関数の(1)~(5)までの部分が何をやっているのかよく分からないので、どなたか解説をお願いします。 int memcmp(const void *s1, const void *s2, size_t n) { const unsigned char *p1 = (const unsigned char *)s1; const unsigned char *p2 = (const unsigned char *)s2; while (n-- > 0) { if (*p1 != *p2) return (*p1 - *p2); p1++; p2++; } return (0); } return (*p1 - *p2); > (1) ---------------------------------------------------------------------- char *strcat(char *s1, const char *s2) { char *p = s1; while (*s1) s1++; /* s1を末尾まで進める */ while (*s1++ = *s2++) ; /* '\0'が見つかるまでs2をコピー */ return (p); } while (*s1++ = *s2++) ; > (2) ---------------------------------------------------------------------- char *strstr(const char *s1, const char *s2) { const char *p1 = s1; const char *p2 = s2; while (*p1 && *p2) { if (*p1 == *p2) { p1++; p2++; } else { p1 -= p2 - s2 - 1; p2 = s2; } } return (*p2 ? NULL : (char *)(p1 - (p2 - s2))); } while (*p1 && *p2) > (3) p1 -= p2 - s2 - 1; > (4) ---------------------------------------------------------------------- char *strcpy(char *s1, const char *s2) { char *p = s1; while (*s1++ = *s2++) ; return (p); } while (*s1++ = *s2++)   > (5) ;          > (5) ----------------------------------------------------------------------

  • このプログラムのどこを直せばいいんでしょうか?

    いま、文字列strの中に文字cが含まれている個数を表示するプログラムを作っているんですが、下のように作っても、上手く行きません。 どこをどう直せばいいのか教えてください! #include <stdio.h> int str_chnum (const char str[],int d) { int i=0; int sum=0; while(str[i]!=0){ if(str[i]==d ){ sum++; } i++; } return(sum); } int main(void) { int c; char str[128]; puts("put sentence..."); scanf("%s",str); puts("search character..."); scanf("%d",&c); printf("there are %d %ds in this sentence.",str_chnum(str,c),c); return(0); }

  • strtol関数をmalloc()関数を使用して次のソースプログラムを

    strtol関数をmalloc()関数を使用して次のソースプログラムを修正しなさいを言われました。 どなたか詳しい方よろしくお願いします。 #include <limits.h> #include <ctype.h> #include <errno.h> #include <stdio.h> int _space_sign(const char *s, const char **endptr); int _space_sign(const char *s, const char **endptr) { int sign ; while (isspace((unsigned char)*s)) ++s; sign = 0; switch (*s) { case '-': sign = -1; // fall through case '+': ++s; break; } *endptr = s; return sign; } long int strtolong(const char * s, char ** endptr, int base) { int c; int sign = _space_sign(s, (const char**)&s); long result; if (s[0] == '0') { ++s; if ((s[1] | 0x20) == 'x') { if (base == 0 || base == 16) { ++s; base = 16; } } else if (base == 0) base = 8; } else if (base == 0) base = 10; result = 0; for (; c = tolower((unsigned char)*s), isdigit(c) || ('a' <= c && c <= 'v'); s++) { int d ; if( isdigit(c) ) d= c - '0' ; else d = c - 'a' + 10; if (d >= base) break; if (result > (LONG_MAX - d - sign) / base) { errno = ERANGE; result = sign ? LONG_MIN : LONG_MAX; } else { result = result * base + d; } } if (endptr != NULL) *endptr = (char*)s; if (sign != 0) result = -result; return result; } int main(void) { char s[128], *e; long n; int base; printf("何進数で変換しますか。"); scanf("%d", &base); printf("変換する数値を入力してください。"); scanf("%s", s); n = strtolong(s, &e, base); if (errno != ERANGE) { printf("変換数値=%ld\n", n); if (*e != '\0') { printf("変換不可能部分=%s\n", e); printf("%d文字目の\'%c\'が変換不可\n", e-s+1, *e); } } else if (n == LONG_MAX) printf("long値で表現できる値を上回りました。\n"); else if (n == LONG_MIN) printf("long値で表現できる値を下回りました。\n"); return 0; }

  • 再帰プログラム

    strに格納されている文字数を数えるプログラムです。 #include<stdio.h> int rstrlen(char *); int main(void) { char str[] = {"abcdefghijk"}; printf("文字数:%d\n",rstrlen(str)); return 0; } int rstrlen(char *p) { if(*p) { p++; printf(p); return 1 + rstrlen (p); } else return 0; } return 1 + rstrlen (p);の部分で再帰をし1をプラスすることにより文字数をカウントしmainのprintfで文字数を表示しているのですがカウントしている値はどこに格納していてどのようにmainに返しているのかが分かりませんでした。教えてください。

  • 文字列検索について

    下記のようなC++プログラムにおいて、Good Morning! の「r」以後が、 検索にひっかからないで、-1を返します。 何故なのか、どうぞよろしくお願いします。 -------------------------------------------------------- #include <iostream> #include <cstring> using namespace std; int flag = 0; // 該当文字があったかどうかのフラグ int strch_idx(const char* s, char c){ int temp; cout << strlen(s) << endl; for(int i=0; i<(signed)strlen(s); i++){ if(*s == c){ temp=i+1; // 配列のインデックスは0オリジンだが、インデックスは1からだから1+する flag = 1; break; } s++; } if(flag == 1) return temp; else return -1; } int main(){ const char* s = "Good Morning!"; int idx = strch_idx(s, 'i'); cout << "検索文字のインデックス:" << idx << endl; return 0; }

  • プログラム問題(1)

    以下の問題のプログラムをやったのですが、コマンドプロンプトで実行してみるとエラーになってしまうのですが、どなたか問題点を指摘していただけないでしょうか? 【問題】 1 西暦1868年から2007年までの年号を入力して和暦に変更して出力するプログラムを作成するプログラム。  例 入力 1868  出力 明治元年       2007     平成19年 【自分でやったプログラム】 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #define streq(a, b) !strcmp((a), (b)) const char *get_era(int); const char *get_era_name(int); int get_era_year(int); void test_get_era(void); int main(int argc, char *argv[]) { int year; char *endptr; const char *era; test_get_era(); if (argc < 2) { fprintf(stderr, "引数を入力してください。\n"); exit(1); } year = (int) strtol(argv[1], &endptr, 0); if (*endptr != '\0') { fprintf(stderr, "数値を入力してください。\n"); exit(1); } era = get_era(year); if (era == NULL) { fprintf(stderr, "西暦を入力してください。(1868-2007)\n"); exit(1); } printf("%s\n", era); return 0; } const char * get_era(int year) { static char buf[256]; int era_year = get_era_year(year); const char *era_name = get_era_name(year); if (era_year == -1) { return NULL; } if (era_year == 1) { sprintf(buf, "%s%s", era_name, "元年"); } else { sprintf(buf, "%s%d%s", era_name, era_year, "年"); } return buf; } int get_era_year(int year) { if (1868 <= year && year <= 1911) { return year - 1867; } if (1912 <= year && year <= 1925) { return year - 1911; } if (1926 <= year && year <= 1988) { return year - 1925; } if (1989 <= year && year <= 2007) { return year - 1988; } return -1; } const char * get_era_name(int year) { if (1868 <= year && year <= 1911) { return "明治"; } if (1912 <= year && year <= 1925) { return "大正"; } if (1926 <= year && year <= 1988) { return "昭和"; } if (1989 <= year && year <= 2007) { return "平成"; } return NULL; } void test_get_era(void) { /* 無効 */ assert(get_era(1867) == NULL); assert(get_era(2008) == NULL); /* 明治 */ assert(streq(get_era(1868), "明治元年")); assert(streq(get_era(1869), "明治2年")); assert(streq(get_era(1911), "明治44年")); /* 大正 */ assert(streq(get_era(1912), "大正元年")); assert(streq(get_era(1913), "大正2年")); assert(streq(get_era(1925), "大正14年")); /* 昭和 */ assert(streq(get_era(1926), "昭和元年")); assert(streq(get_era(1927), "昭和2年")); assert(streq(get_era(1988), "昭和63年")); /* 平成 */ assert(streq(get_era(1989), "平成元年")); assert(streq(get_era(1990), "平成2年")); assert(streq(get_era(2007), "平成19年")); }

  • 関数の作り方

    文字列s1に文字列s2が含まれるか判定する関数search を作りたいのですが、コンパイルできません。 どこに問題がありますか?? #include<stdio.h> #include<string.h> int seach(char *s1,char *s2) { char *p; p = strstr(s1,s2); if(p == NULL){ return 0; }else{ return 1; } } main(void){ char s1[255]; char s2[255]; int res; printf("文字列s1を入力:"); scanf("%s",s1); printf("文字列s2を入力:"); scanf("%s",s2); res = search(s1,s2); if(res == 1){ printf("文字列s1に文字列s2が含まれます\n"); } if(res == 0){ printf("文字列s1に文字列f2は含まれません\n"); } return 0; }

  • C言語のプログラム問題に対応するBNFの書き方がわかりません

    C言語のプログラムからBNFにする方法を習っているのですが、どうしてもそのやり方がわかりません。 下にあるプログラムに対応するBNFを自分で作成してみたのですが、 <A>::=A|Bぐらいしかできませんでした。このBNFを作っても、なぜこうなるのかもわかりません。 #include<stdlib.h> #include<stdio.h> #include<string.h> enum symboltype{SMILE,HELLO,BYE,END}; void A(); void B(); void scan(); void error(char *msg); enum symboltype next; int main(int argc, char* argv[]){ scan(); A(); if(next != END) error("#PARSE ERROR#"); else puts("#PARSE OK#"); return 0; } void A(){ if(next != SMILE) error("#PARSE ERROR#"); else puts("#PARSE OK#"); return 0; } void B(){ if(next != SMILE){ scan(); return; }else if(next != HELLO){ scan(); A(); if(next != BYE) error("#PARSE ERROR#"); scan(); }else error("#PARSE ERROR#"); } void error(char *msg){ puts(msg); exit(1); } void scan(){ char buff[10]; if(fgets(buff,10,stdin)==NULL){ next=END; return; } if(strcmp(buff,"hello\n")==0) next=HELLO; else if(strcmp(buff,"bye\n")==0) next=BYE; else if(strcmp(buff,"(*_*)\n")==0) next=SMILE; else error("#UNKNOWN TOKEN#"); } このプログラムに対応するBNFを教えてほしいんです。 お願いしますm(_ _)m また、BNFはどのように書くのかも教えていただけませんか。