質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

3185閲覧

[C言語]コマンド文字列検索をしたいです。おそらくアルゴリズムです。

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2015/04/21 07:46

txtファイルに入ってる文字列から、コマンドで入力された文字を検索してその文字が入ってる行番号も一緒に返したいです。
しかしバグがあって、検索できない文字列があったり、検索した文字が入ってない行も返ってしまいます。
よろしかったらこのバグを教えてください。

ソース↓

lang

1 2#include <stdio.h> 3#include <string.h> 4#include <math.h> 5 6#define N 3 7#define SIZE 100 8#define MAX 10000 9int sindex[MAX][SIZE] = { {0} }; 10char line[MAX][SIZE] = {}; 11 12int make_index( char* path ); 13int search( char* str ); 14 15/* 4文字以上の文字列の検索 */ 16int main(void) 17{ 18 make_index( "./doc.txt" ); 19 char input[SIZE]; 20 int j, k, c, t; 21 while(1){ 22 printf("検索したい文字列(%d文字以上)を入力してください。: ", N+1); 23 scanf("%s", input); 24 if ( strcmp(input, "q" )==0 ){ break; } 25 int len = strlen( input ); 26 if ( len < N+1 ){ 27 printf("入力した文字列は%d文字未満です。\n", N+1); 28 continue; 29 } 30 c = 0; 31 t = 0; 32 int count_list[SIZE][MAX] = {{0}}; 33 for( k=0; k < SIZE-N; k++ ){ 34 if ( input[k+N-1] == '\0' || input[k+N-1] == '\n'){ break; } 35 char buf[N]; 36 int m; 37 for( m = 0; m < N; m++ ){ buf[m] = input[k+m]; } 38 int i = search( buf ); 39 if ( i >= 0 && i < MAX ){ 40 for ( j = 0; j < SIZE; j++ ){ 41 if ( sindex[i][j] > 0 ){ 42 count_list[j][i]++; 43 c++; 44 }else{ 45 count_list[j][i] = 0; 46 } 47 } 48 } 49 t++; 50 } 51 52 int m = 0; 53 int k = 0; 54 int x = 0; 55 for( j = 0; j < SIZE; j++ ){ 56 m = 0; 57 for ( k = 0; k < MAX; k++ ){ 58 if ( count_list[j][k] > 0 ){ m+=count_list[j][k]; } 59 } 60 if ( m >= t ){ 61 printf("\t[%d]\t[%s]\n", j+1, line[j]); 62 x++; 63 } 64 } 65 if ( x > 0 ){ 66 printf("==> %d 件見つかりました。\n", x ); 67 } 68 else{ 69 printf("%s は見つかりませんでした。\n", input); 70 } 71 } 72 return -1; 73} 74 75// インデックス配列から検索 76// 見つかったら第1添え字を返す 77int search( char* str ) 78{ 79 int y = 0; 80 int j; 81 for ( j = 0; j < N; j++ ) 82 y += ( str[j] - '0' ) * pow(10,j); 83 return y; 84} 85 86// ファイルからインデックスの作成 87int make_index( char* path ) 88{ 89 FILE* fp = fopen( path, "r" ); 90 if ( fp == NULL ){ 91 printf("%s: file open error.\n", path ); 92 return -1; 93 } 94 int i, j, x; 95 char s[256]; 96 // インデックス配列の初期化 97 for (i=0; i<MAX; i++){ 98 for(j=0; j<SIZE; j++){ 99 sindex[i][j] = 0; 100 } 101 } 102 x = 0; 103 while( fgets( s, SIZE, fp ) != NULL ){ 104 strcpy( line[ x ], s ); 105 for( i=0; i<SIZE; i++){ 106 for( j = 0; j<SIZE; j++){ 107 if ( line[i][j] == '\n' ){ line[i][j] = '\0'; break; } 108 } 109 } 110 for( i=0; i < SIZE-N; i++ ){ 111 char ngram[N]; 112 int y = 0; 113 for ( j = 0; j < N; j++ ){ 114 if ( s[i+j] == '\0' || s[i+j] == '\n' || s[i+j] == '_'){ break; } 115 y += ( s[i+j] - '0' ) * pow(10,j); 116 } 117 if ( j == N ){ 118 sindex[y][x] += 1; 119 } 120 } 121 x++; 122 } 123 fclose(fp); 124 return 1; 125}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ざっと見て気になったところは make_index関数内の

lang

1 for( i=0; i<SIZE; i++){ 2 for( j = 0; j<SIZE; j++){ 3 if ( line[i][j] == '\n' ){ line[i][j] = '\0'; break; } 4 } 5 }

ここ、外側のforループは i < MAX としないと、100行目以降は改行コード外しができていないんじゃないですか?

投稿2015/04/21 17:05

編集2015/04/21 17:07
KoichiSugiyama

総合スコア3041

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

正しいソースコードを作成することが出来ました。ご協力ありがとうございました。
コード↓

lang

1#include <string.h> 2#include <math.h> 3 4#define N 3 5#define SIZE 100 6#define MAX 18000 7#define FLAG -1 //flagを作成 8 9int sindex[MAX][SIZE][SIZE] = {{ {0} }};//2次元配列から3次元配列に変更. 10int sindex_i[MAX][SIZE] = { 0 }; //sindexのindexを作成. 11char line[MAX][SIZE] = {}; 12 13int make_index( char* path ); 14int search( char* str ); 15 16/* 4文字以上の文字列の検索 */ 17int main(void) 18{ 19 make_index( "./doc.txt" ); 20 21 char input[SIZE]; 22 int j, k, c, t; 23 24 while(1){ 25 printf("検索したい文字列(%d文字以上)を入力してください。: ", N + 1); //演算子間に空白 26 scanf("%s", input); 27 if ( strcmp(input, "q" ) == 0 ) //空白 28 break; //改行 29 int len = strlen( input ); 30 if ( len < N + 1 ){ 31 printf("入力した文字列は%d文字未満です。\n", N + 1); //空白 32 continue; 33 } 34 c = 0; 35 t = 0; 36 int count_list[SIZE] = { 0 }; //2次元配列から1次元配列に変更した. 37 int temp = -1; 38 for( k = 0; k < SIZE - N /*空白*/; k++ ){ 39 if ( input[k+N-1] == '\0' || input[k+N-1] == '\n') 40 break; 41 char buf[N]; 42 int m; 43 for( m = 0; m < N; m++ ) 44 buf[m] = input[k+m]; 45 int i = search( buf ); 46 if ( i >= 0 && i < MAX ){ 47 for ( j = 0; j < SIZE; j++ ){ 48 for(m = 0; m < sindex_i[i][j] && temp > 0; m++) 49 if ( sindex[i][j][m] > 0 ){ 50 for(c = 0; c < sindex_i[temp][j]; c++) 51 if(sindex[i][j][m] - sindex[temp][j][c] == 1) 52 count_list[j]++; 53 }else{ 54 count_list[j] = 0; 55 } 56 } 57 temp = i; 58 } 59 t++; 60 } 61 62 //int m = 0;は必要ない. 63 int k = 0; 64 int x = 0; 65 for( j = 0; j < SIZE; j++ ){ 66 // m = 0; 67 //for ( k = 0; k < MAX; k++ ){ 68 //if ( count_list[j][k] > 0 ) //改行 69 //m += count_list[j][k]; //空白 70 //} 71 if ( count_list[j] >= t - 1 ){ 72 printf("\t[%d]\t[%s]\n", j+1, line[j]); 73 x++; 74 } 75 } 76 if ( x > 0 ){ 77 printf("==> %d 件見つかりました。\n", x ); 78 } 79 else{ 80 printf("%s は見つかりませんでした。\n", input); 81 } 82 } 83 return -1; 84} 85 86// インデックス配列から検索 87// 見つかったら第1添え字を返す 88int search( char* str ) 89{ 90 int y = 0; 91 int j; 92 for ( j = 0; j < N; j++ ) 93 y += ( str[j] - 'a' ) * pow( 'z' - 'a' + 1, j ); 94 return y; 95} 96 97// ファイルからインデックスの作成 98int make_index( char* path ) 99{ 100 FILE* fp = fopen( path, "r" ); 101 if ( fp == NULL ){ 102 printf("%s: file open error.\n", path ); 103 return -1; 104 } 105 106 int i, j, x; 107 char s[256]; 108 // インデックス配列の初期化 109 for (i = 0; i < MAX; i++){ 110 for(j = 0; j < SIZE; j++){ 111 for(x = 0; x < SIZE; x++) 112 sindex[i][j][x] = 0; 113 } 114 } 115 116 x = 0; 117 while( fgets( s, SIZE, fp ) != NULL ){ 118 strcpy( line[ x ], s ); 119 for( i = 0; i < SIZE/*演算子間に空白*/; i++){ 120 for( j = 0; j < SIZE/*演算子間に空白*/; j++){ 121 if ( line[i][j] == '\n' ){ //改行 122 line[i][j] = '\0'; 123 break; 124 } 125 } 126 } 127 128 for( i = 0; i < SIZE - N/*演算子間に空白*/; i++ ){ 129 char ngram[N]; 130 int y = 0; 131 for ( j = 0; j < N; j++ ){ 132 if ( s[i+j] == '\0' || s[i+j] == '\n' || s[i+j] == '_') 133 break; 134 y += ( s[i+j] - 'a' /*値を小さくしている*/) * pow( 'z' - 'a' + 1, j);//衝突の回避をしている. 135 } 136 if(s[i+j] == '\0') 137 break; 138 if ( j == N ){ 139 sindex[y][x][sindex_i[y][x]++] = i;//順序関係を記憶している. 140 } 141 } 142 x++; 143 } 144 fclose(fp); 145 return 1; 146} 147コード

投稿2015/04/22 09:00

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

提示したソースから察するにそれなりにC言語をわかっていること前提と見受けられます。
これほどのソースが書けるのであればバグについてもそれなりに見当がついてるのではないでしょうか?

投稿2015/04/21 15:12

shu21

総合スコア106

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問