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

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

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

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

Q&A

解決済

2回答

803閲覧

単語照合プログラムについて

papikonoqui

総合スコア10

C

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

0グッド

0クリップ

投稿2021/05/24 10:34

前提・実現したいこと

与えられた単語(以下、クエリと示す)が標準入力されたファイルに対して、含まれていればその一文を出力しようとしています。
(例)
標準入力するファイルtext.txtは以下のようなものとします。
............text.txt................
I was a child.
I can do it as well.
....................................

ここで $ ./a.out "AS" ./text.txt
で実行すると
I can do it as well.
と出力されるようにしたいと考えています。

発生している問題・エラーメッセージ

実行;./a.out "AS" ./text.txt 上記で実行したところ何も出力されませんでした。

該当のソースコード

c言語

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <ctype.h> 5 6int main(int argc, char* argv[]){ 7 FILE *fp; 8 char buffer[1024]; 9 char query[256]; 10 char temp[256]; 11 char *delimiter = " .,:;?!()"; 12 int n = 0; 13 char *s; 14 int i; 15 16 if(argc != 3){ 17 printf("parameter error\n"); 18 exit(1); 19 } 20 21 // 第2引数をクエリとしてコピー 22 strcpy(query, argv[1]); 23 i = 0; 24 while(query[i] != '\0'){ 25 query[i] = toupper(query[i]); 26 i++; 27 } 28 29 if((fp = fopen(argv[2], "r")) == NULL){ 30 printf("file open error\n"); 31 exit(1); 32 } 33 34 while(fgets(buffer, sizeof(buffer), fp) != NULL){ 35 buffer[strlen(buffer) - 1] = '\0'; 36 //読み込んだ一列をtempに保存(出力用) 37 strcpy(temp, buffer); 38 39 // 大文字に統一 40 for(i=0; buffer[i] != '\0'; i++){ 41 buffer[i] = toupper(buffer[i]); 42 i++; 43 } 44 45 // strtok関数を利用して単語ごとで抜き出し、クエリと比較 46 s = strtok( buffer , delimiter ); 47 if ( s != NULL ) { 48 // クエリと単語が一致すれば、その一文を出力 49 if(strcmp(s, query) == 0){ 50 printf("%s\n", temp); 51 } 52 } 53 54 while( ( s = strtok( NULL , delimiter ) ) != NULL ) { 55 if(strcmp(s, query) == 0){ 56 printf("%s\n", temp); 57 } 58 } 59 60 61 } 62 63 fclose(fp); 64 65 exit(0); 66} 67

補足情報(FW/ツールのバージョンなど)

strtok関数を用いて,予め定義しておいたdelimiterで単語ごとに区切り、先頭アドレスをsに代入しています。
sと入力単語(query)が等しければ、その文が出力されるようにしたのですが、何も出力はされませんでした。
どなたかご教示していただけると幸いです。

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

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

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

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

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

kaina

2021/05/24 11:53

解決済みですが、例えば「I can't fly.」という英文で「can」という単語が含まれているか 検索した場合、「can't」は対象外となりますが別単語扱いで問題ありませんか?
papikonoqui

2021/05/24 13:03

上記のソースコードで「can」を検索すれば、「can't」は対象外となります。 今回は区切り文字としてdelimiterを定義していますが、その中にシングルクオートを加えたときは「can't」も対象となります。 実行し確認しました。
kaina

2021/05/24 13:28

英語の略語を厳密にやろうとすると中々奥が深くシングルクォートをデリミタとして定義すると 今度は「didn't」みたいな場合もあるので厄介です。 何を言いたかったかというと人によって定義がぶれる様な内容がある場合、 パターンを洗い出し仕様を定義すると一段階上のプログラムが作れるようになれますので、 頭の片隅にでも置いていただければ幸いです。
guest

回答2

0

ベストアンサー

大文字化のループで、1回のループでiを2回インクリメントしてます。

投稿2021/05/24 11:14

otn

総合スコア84538

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

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

papikonoqui

2021/05/24 11:31

無事に動作しました!ありがとうございます。
guest

0

別に単語単位で区切らなくても文字列検索(strstr関数なり自作なり)すればいいだけと思いますよ。ちなみに例のコマンドの場合はダブルクオートを除外する必要があります。

投稿2021/05/24 11:09

HogeAnimalLover

総合スコア4830

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

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

papikonoqui

2021/05/24 11:20

すみません、説明が不十分でした。strstr関数用いた場合、標準入力で"AS"としたときにwasという単語にasが含まれているため、その文を出力してしまいます。あくまでもasという単語そのものを検索したいと考えています。 例のコマンドの件ですが、ダブルクオートを除外しても変わらず、出力はサれませんでした。
HogeAnimalLover

2021/05/24 11:56

おお。ダブルクオートの除外は自動でされたようですね。失礼しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問