
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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バイナリファイルをテキストフ...
-
C/C++ ファイル入出力操作 (長...
-
テキストファイルの中身をまと...
-
0バイトファイルの作成
-
【VB.Net】バイト型配列に読み...
-
どんなプログラムを書いても指...
-
C言語初心者の質問失礼します。
-
Access クエリ実行が急に非常に...
-
ファイル名の先頭にアンダース...
-
エクセルVBA 2千万行のCSVファ...
-
vba ActiveSheet.pasteを使った...
-
VB.NETで他のプロジェクトで作...
-
他の.CPPファイルに定義した関...
-
フルパスから最後のディレクト...
-
VBA バイナリ―から文字列にす...
-
ファイルやディレクトリの存在...
-
JavaScriptでコマンドプ...
-
コンポーネント`MSCOMM32.cox'...
-
fopenで別ディレクトリにファイ...
-
ASP .NETでファイル選択ダイア...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バイナリファイルをテキストフ...
-
ファイル内のデータを1行削除...
-
fgetsで2行目から文字化け
-
テキストファイルの行数を取得...
-
c言語 2つのファイルを行ご...
-
巨大なテキストファイル(可変...
-
ファイルへの落とし方について
-
ファイル名をチェックする方法。
-
【VB.Net】バイト型配列に読み...
-
続jファイルに文字列を書く
-
配列のメモリの確保
-
C言語での採番について
-
ファイル読み込みについて
-
(UWSC)このような場合、解決策...
-
ファイル関数について
-
C言語 ; で区切った文字を別...
-
VBSで指定行に挿入
-
winsock recvでの文字化け
-
freadでファイルを読み込んだ際...
-
VisualC++でのバイナリファイル
おすすめ情報