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

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

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

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

Q&A

解決済

1回答

436閲覧

どこがおかしいのか分かりません。教えて下さい。

ryusei_12

総合スコア11

C

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

0グッド

0クリップ

投稿2020/04/16 21:26

どこがおかしいか見つかりましたら教えていただきたいです。
現在、自分はC言語で文字列検索の関数を簡単に作成しております。
条件
・ワイルドカード"+"があれば、任意の1文字へ置き換えることが可能とします。

以下に作成したコードを載せます。

C

1#include <stdio.h> 2#include <stdint.h> 3#include <string.h> 4 5#define FOUND (0) 6#define NOT_FOUND (1) 7#define ERROR (-1) 8#define TARGET_MAX (255) 9#define CHECK_MAX (255) 10#define WILDCARD ('+') 11 12typedef int8_t int8; 13typedef uint16_t uint16; 14int8 string_search(char* target_string, char* check_string, char* result); 15 16int main(int argc, char* argv[]) { 17 //argv[0]->起動プログラム 18 //argv[1]->第一引数(対象文字列) 19 //argv[2]->第二引数(検索文字列) 20 int8 ret;//戻り値を格納 21 char target[TARGET_MAX]; //対象文字列を格納 22 char check[CHECK_MAX]; //検索文字列を格納 23 char result[CHECK_MAX]; //見つけた文字列を格納(出力引数) 24 25 strcpy(target, argv[1]);//対象文字列(argv[1])をtargetに格納するためマジックナンバーを使用 26 strcpy(check, argv[2]);//検索文字列(argv[2])をcheckに格納するためマジックナンバーを使用 27 28 ret = string_search(target, check, result); 29 //結果の表示 30 if (ret == FOUND) { 31 printf("%s\n",result); 32 return FOUND; 33 } else if (ret == NOT_FOUND) { 34 printf("検索できませんでした。\n"); 35 printf("%s\n",result); 36 return NOT_FOUND; 37 } else { 38 return ERROR; 39 } 40} 41 42int8 string_search(char* target_string, char* check_string, char* result) { 43 uint16 target_len; //対象文字列の文字数を格納 44 uint16 check_len; //検索文字列の文字数を格納 45 uint8_t i_c; //ループ変数 46 uint8_t check_position; //検索文字の位置を指定するのに使用 47 uint8_t mem_position; //resultに記憶する時の要素を指定する時に使用 48 uint8_t result_len; //resultの文字数を格納 49 target_len = strlen(target_string); 50 check_len = strlen(check_string); 51 52 //入力された対象文字列、検索文字列の数を確認 53 if ((target_len > TARGET_MAX) || (check_len > CHECK_MAX)) { 54 return ERROR;//異常終了 55 } 56 57 check_position = 0; 58 mem_position = 0; 59 //検索開始 60 for (i_c = 0; i_c < target_len; i_c++) { 61 /*'+' または一致文字があった場合の処理*/ 62 if ((check_string[check_position] == WILDCARD) || (check_string[check_position] == target_string[i_c])) {//WILDCARDが検索文字列内に出現したら 63 result[mem_position] = target_string[i_c];//出力引数にコピー 64 result_len = strlen(result);//何文字出力引数にコピーしたか確認(このあたりがおかしいのかな?? 65 if (result_len >= check_len) { 66 //記憶した文字数が検索文字数と同じ数になれば終了 67 return FOUND; 68 } 69 check_position++; 70 mem_position++; 71 continue; 72 } 73 //それ以外の場合(検索文字にマッチしなかった場合 74 check_position = 0; 75 mem_position = 0; 76 } 77 return NOT_FOUND; 78}

テスト結果
1.(7文字の検索までならきちんと処理できています。
対象文字列 検索文字列  結果
abcdefghij  +++++    abcde

2.(8文字以降は処理がおかしい)

なぜ8文字以降だと処理がうまくできていないのか原因がわからないです。
なので、気づいた方がいらっしゃいましたら是非教えていただけると、嬉しく思います。

以上です。
よろしくお願いいたします。

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

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

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

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

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

thkana

2020/04/16 22:14

解決してるのでコメントだけ。 期待しない現象が起きた時に「おかしい」「うまくできていない」で切り捨ててしまうのではなく、起きた現象(例えば余計な文字列が付加されるとか)をきちんと捉えて「なぜそうなったか」を考えることは解決へのひとつのアプローチかと思います。
guest

回答1

0

ベストアンサー

result_len = strlen(result);//何文字出力引数にコピーしたか確認(このあたりがおかしいのかな??

ご推察通り、この近辺です。

C言語は文字列としてヌル終端文字列という仕様を採用しております。
つまりresultの末尾が\0である必要があります。

投稿2020/04/16 22:00

asm

総合スコア15147

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

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

ryusei_12

2020/04/16 22:04

なるほど。 納得しました。そういえば、そのような仕様でしたね。。。 教えていただきありがとうございます。 助かりました。
ryusei_12

2020/04/16 22:14

すみません。 確認せずにベストアンサーにしたのですが、やはりうまく動作しないですね。。。 result_len = strlen(result);//何文字出力引数にコピーしたか確認(このあたりがおかしいのかな?? これの後に、 result[result_len] = '\0' を追加しました。 うまく動作するかと、思ったのですがやはり8文字以降おかしかったです。 原因わかります、、、?
asm

2020/04/16 22:21

strlen(result)は`\0`を探すので この時点で末尾の`\0`が正しい位置にないといけません。 (ついでに言うと、正しい位置=書き込んだ文字数+1なのでstrlen(result)する必要性すら疑問です。) 代わりに result_len = mem_position; result[result_len+1] = '\0'; ですね
ryusei_12

2020/04/16 22:25

すみません。。。 間抜けなコメントをしました。 ありがとうございます。
asm

2020/04/16 22:29

あ、すいません。 誤: result_len = mem_position; 正: result_len = mem_position+1; result[result_len] = '\0'; でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問