C言語の勉強として以下のような簡単なプログラムを作りました。
テキストファイルからユーザが入力した単語を検索し、ヒットしたものだけ
その単語とその説明を表示するというプログラムです。
正常に動いているようなので、
つぎはループごとに、読み込んだ文字数に合わせて
配列(mean)の要素数を動的に確保するということを
しようと思うのですがどのタイミングでmallocやreallocを入れればよいのか
いまいちよくわかりません。
また、このプログラムの欠点などありましたら教えていただけると助かります。
よろしくお願いします。
---------------------------------------------------------------------
//マイ単語帳プログラム
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
main(){
char input[100];//ユーザが入力した文字列を格納
char tango[200];//ファイルの単語
char mean[1000];//ファイルの説明
char conti;//検索を続けるかどうかの入力
int flag;//検索単語がヒットした場合に立てるフラグ
FILE *fp;
//単語ファイルのopen
if((fp=fopen("tango.txt","r"))==NULL){
printf("ファイルが開けません。");
exit(1);
}
/*******************ファイルからの文字列読み込み****************************/
//Yが入力されるまで検索を続ける
do{
printf("検索する単語を入力してください。\n");
scanf("%s",input);
printf("検索対象:%s\n\n",input);
flag=0;//ヒットしたかどうかのフラグの初期化
while((fscanf(fp," %s %s",tango,mean))!=EOF){//fscan 書式を指定して読み込める。
if(strcmp(tango,input)==0){//strcmpは2つの引数が同じ時0を返す
printf("%s\n%s\n\n\n",tango,mean);
flag=1;//ファイル内に単語があった場合にフラグを立てる。
}
}
rewind(fp);
if(flag==0){
printf("その単語は登録されていません。\n");
}
printf("検索を終了しますか? ==> Y\n");
printf("検索を続けるにはY以外の文字を入力してください。\n");
scanf(" %c",&conti);//scanfの問題点を回避するために読み込み前に半角スペース
}
while(conti!='Y');
/**************************************************************************/
fclose(fp);
return;
}
----------------------------------------------------------------
tango.txt
apple リンゴ
SMTP 電子メールの送信や転送を行うためのプロトコル。
rewind 形式:rewind(ファイルポインタ); C言語のファイルシステム関数。ファイルの現在位置をファイルの先頭に置くことができる。
No.2ベストアンサー
- 回答日時:
>やはりできないのですかね?(^_^;)
meanを読み込む前にmeanのサイズを取得する方法がないと…無理でしょうね。
あるいは…1文字(1バイト)ずつ読み込んで、改行位置に到達しなかったらrealloc()で拡張して、さらに1文字(1バイト)読み込む…とか。
realloc()自体は1バイト単位でやる必要は無いかも知れませんけどね。
# そこらヘンは http://oshiete.goo.ne.jp/qa/6961996.html 辺りでも話題になってますが。
>要するにヒットしたらすぐに抜け出す方が効率がいいということですかね?
>テキストファイルのインデックスは重複しないように作成するつもりです。
仕様次第…です。
man (成人の)男,男子
man [無冠詞で総称的に] (女と対比して)男
man オンラインリファレンスマニュアルのインターフェース
とか、複数の意味があるものを無視するかどうか…でしょう。
最初にヒットしものだけ。重複はない。というのであれば、ヒットした時に読み込みループを抜けた方が動作としては軽い…かと。
>strcmpする前にワンクッションおいて大文字小文字を区別しないような動作を入れるといいということでしょうか?
stricmp()を使う。なんて方法もあります。
input[]に入るのが、ASCIIの場合に限るかも知れませんけど。
# shift-jisが入った場合にstricmp()が正しく動作するかは…ライブラリ次第でしょうな。
前回のアドバイスをいただいてからさっそくstricmp()使っているのですが、
文字コードのことまではまったく考えていませんでした。
というか、文字コード自体についてほとんど理解していないのでそこから
勉強する必要がありそうです(笑)
>最初にヒットしものだけ。重複はない。というのであれば、ヒットした時に読み込みループを抜けた方が動作としては軽い…かと。
もう少し検討してみます!
No.1
- 回答日時:
>配列(mean)の要素数を動的に確保するということを
>しようと思うのですがどのタイミングでmallocやreallocを入れればよいのか
>いまいちよくわかりません。
もちろん、実際に読み込む前です。
が、読み込んでみないと長さが判らないので…どうにも出来なさそうですが……。
>また、このプログラムの欠点などありましたら教えていただけると助かります。
お約束ですが、バッファオーバーフローの可能性は残ったまま…でしょう。
input[]とtango[]でサイズが違う。という意図も不明ですが。
input[]に入力したデータがtango.txtの先頭にあったとしても、最後まで読み込みを継続している…とか。
# まぁ、最後まで読んでいるのでtango.txtに同一の単語があった場合に全て表示することになりますが。
strcmp()を使用しているため、例のパターンだと"Apple"はヒットしない…とか。
>どうにも出来なさそうですが……。
やはりできないのですかね?(^_^;)
>input[]とtango[]でサイズが違う。という意図も不明ですが。
ソースをここにペーストしたときに自分も気づきました(笑)
とりあえずそのまま張り付けた方がいいと思い修正しませんでした。
直しておきます。
>input[]に入力したデータがtango.txtの先頭にあったとしても、最後まで読み込みを継続している…とか。
要するにヒットしたらすぐに抜け出す方が効率がいいということですかね?
>まぁ、最後まで読んでいるのでtango.txtに同一の単語があった場合に全て表示することになりますが。
検索するのはスペース前のインデックス(tango)だけなのでmeanの方で重複しても関係ないので気にしていませんでした。
テキストファイルのインデックスは重複しないように作成するつもりです。
>例のパターンだと"Apple"はヒットしない…とか。
strcmpする前にワンクッションおいて大文字小文字を区別しないような動作を入れるといいということでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
テキストファイルの行数を取得...
-
バイナリファイルをテキストフ...
-
ファイル内のデータを1行削除...
-
VBSで指定行に挿入
-
fopenで開いたファイルのサイズ...
-
freadとfwrite
-
C言語のファイル読み込みに関し...
-
fgetsで2行目から文字化け
-
C言語初心者の質問失礼します。
-
フルパスから最後のディレクト...
-
バッファとは何ですか
-
GetPrivateProfileStringでini...
-
csvファイルを開かずに文字を検...
-
FTPでputすると空ファイルが出...
-
ACCESSのEXEを作るのは可能...
-
どんなプログラムを書いても指...
-
ファイル名の先頭にアンダース...
-
Access クエリ実行が急に非常に...
-
SGファイルって何ですか?
-
ExcelVBAでカレントディレクト...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ファイル内のデータを1行削除...
-
バイナリファイルをテキストフ...
-
fgetsで2行目から文字化け
-
テキストファイルの行数を取得...
-
c言語 2つのファイルを行ご...
-
C言語での改行コードの扱いにつ...
-
改行までの一文字ずつのファイ...
-
VBSで指定行に挿入
-
【VB.Net】バイト型配列に読み...
-
freadとfwrite
-
巨大なテキストファイル(可変...
-
0バイトファイルの作成
-
fopen(書き込みモード)でファイ...
-
fopenで開いたファイルのサイズ...
-
winsock recvでの文字化け
-
ファイルサイズ指定し、ファイ...
-
fortranで文字列を読み込む際の...
-
【C言語】テキスト読み込みの行...
-
C言語での採番について
-
VS2010 MFC CStdioFileについて
おすすめ情報