フラッシュメモリやハードディスクへファイルの書き出しをfwriteで行い、
作成したファイルをfreadを使って読み込み、その前後でclock関数を呼ぶことで
読み書きの処理時間を算出するプログラムを作成しています。
具体的には以下のような処理を行わせています。


//書き込み用のバッファを作成
buf_w = (unsigned char*)malloc(BUFSIZE);
memset(buf,0,BUFSIZE);
//ファイル書き込み処理
fp = fopen("ファイル名","wb");
start = clock();
fwrite(buf_w,BUFSIZE,1,fp);
end = clock();
fclose(fp);


//読み出し用のバッファを作成
buf_r = (unsigned char*)malloc(BUFSIZE);
//ファイル読み出し処理
fp = fopen("ファイル名","rb");
start = clock();
fread(buf,BUFSIZE,1,fp);
end = clock();
fclose(fp);


以上の処理にて、BUFSIZEが1GB程度の場合は問題ないのですが、
BUFSIZEを200MB程度に減らした場合に読み込み速度が
ありえないほど速くなってしまうという問題が発生してしまいます。
(HDDやフラッシュメモリからの読み込みなのに転送速度が1000MB/sオーバーとか)

RAMDISKとして設置したXドライブで試すと読み書き共に1200MB/sくらいになるので、
もしかしたらメモリにキャッシュされたデータを直接読み込んでしまっているのでは……
などと考えているのですが、試行錯誤すれども回避策が思い浮かびません。

どなたか、この現象について心当たりのある方がいらっしゃいましたら何かアドバイスいただけると幸いです。
宜しくお願いいたします。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

こういう目的でfreadのような高水準I/O関数使うと正確な結果は得られません。



WindowsならWinAPI,Linuxならシステムコール使い、
キャッシュを使用しない設定でファイルを開いて読み書きすれば、それなりに安定したデータが得られると思います。

あと一回で1GBもメモリ確保したらスラッシングが起きてませんかね?
これも結果を不正確にする要素なのでもう少し小さいサイズ(20MB位)から始めた方がいいです。
    • good
    • 0
この回答へのお礼

ご回答有難うございます。

やはり低水準入出力使わないと駄目でしたか……
Linuxのシステムコールは若干経験があったのですが、WindowsではWINAPIを使えば良かったのですね。キャッシュを無効にして読み出す方法がある事を知り大変勉強になりました。

ご指摘の通り、WIN32APIのCREATE_FILEでFILE_FLAG_NO_BUFFERINGのフラグを立てて読み出しを行ったところ、ほぼ正確な値を得ることができました。
悩んでいた事を解決できすっきりしました。

メモリ確保容量も確かに1GBはどう考えてもまずいですよね。こちらも再考してみます。有難うございました。

お礼日時:2008/10/23 23:09

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q英語キーボードが使えて高性能なネットブック

英語キーボードが使えて高性能なネットブックを探しています。
・必須条件
2Kg未満、RAM2GB以上、解像度1024x768以上、10万円または$1000未満
・できれば欲しい条件
デュアルコア、高機能Video、DVDドライブ内臓、OSは無/XP/7
自分で探した範囲では、「HP Pavilion dv2z(L625)の米国版」、「ASRock Multibook G22(Prime Note Cresion NAの元?)」等がありました。
Q1. これらは、日本で入手可能でしょうか?(HPの米国サイトではNGでした)
Q2. 英語キーボードつきまたは交換可能な他の候補が何かありますでしょうか?
Q3. その他何か良い方法や裏技、情報(そのうち○社から出るなど)をご存知であればお教えください。

Aベストアンサー

回答が得られないのは必須条件を満たす市販製品が見当たらないからだと思われ
ます.かろうじて Lenovo ThinkPad X200s 200 台限定 Model で英語 Keyboard
+ 2GB RAM, XPpro Downgrade 付で \100,905 です↓
http://shopap.lenovo.com/SEUILibrary/controller/e/jpweb/LenovoPortal/ja_JP/systemconfig.runtime.workflow:LoadRuntimeTree?sb=:000000AD:00000136:&smid=09E202623C724E77B3580608BB1C1392
もしくは \86,100 で VISTA Home Premium → Win7 優待 Upgrade ですか.

後は Dell Inspiron Mini12 だと 2GB RAM BTO 不可(1GB RAM のみ)で
条件外です(英語 Keyboard,予算,重量,解像度,OS は満たすが)
BTO で英語 Keyboard があるのは Dell と Lenovo しか私は知りません.
価格的には欲しい条件の殆どは満たせないのが現実と思われます.

回答が得られないのは必須条件を満たす市販製品が見当たらないからだと思われ
ます.かろうじて Lenovo ThinkPad X200s 200 台限定 Model で英語 Keyboard
+ 2GB RAM, XPpro Downgrade 付で \100,905 です↓
http://shopap.lenovo.com/SEUILibrary/controller/e/jpweb/LenovoPortal/ja_JP/systemconfig.runtime.workflow:LoadRuntimeTree?sb=:000000AD:00000136:&smid=09E202623C724E77B3580608BB1C1392
もしくは \86,100 で VISTA Home Premium → Win7 優待 Upgrade ですか.

後は Dell Inspiron Mini12 だ...続きを読む

Qfreadでcsvファイルを読み込んだ後、改行コードを終端文字に変換し

freadでcsvファイルを読み込んだ後、改行コードを終端文字に変換したいです。
どのように変換したらいいでしょうか?
C++初心者です。よろしくおねがいいたします。

Aベストアンサー

Caution:
以下の回答はstrtok()の仕様を知らないとドツボにはまる可能性が非常に高くなります。
また、CSVの仕様では「改行込みのデータを許す」ためこの方法だと改行込みデータは解析不能です。

要するに一括で取ってきたファイルの中身を行単位で拾いたい、ということですよね?
であればstrtok()で分割しながら取っていくのが楽でしょう。

char *p; // fread()で読み込んだデータ本体 領域は別途malloc()等で確保
char *t; // 切り出した行の先頭を指すポインタ

...(中略)...

t = strtok(p, "\r\n");
while(t != NULL)
{
...
t = strtok(NULL, "\r\n");
}

Q英語OSでのIME日本語変換

日本語の漢字変換への性能がすごく悪いのですが、何か改善する方法があればアドバイス下さい。日本語版officeは海外在住で手に入らない為、それ以外の方法を教えて頂ければ幸いです。
環境;
WindowsXP(英語版)SP3
officeXP(英語版)
IMEスタンダード2002

Aベストアンサー

ATOKなら、体験版もあるし、DL販売もしてます。

http://www.atok.com/

又、OFFICE 2007には試用版があり、Office IME 2007も含まれています。
(WORD等の本体ソフトは試用版なので使用制限が存在するが、IME2007には制限が無い。)

http://trial.trymicrosoftoffice.com/trialjapan/default.aspx?re_ms=oo&culture=ja-JP
http://trial.trymicrosoftoffice.com/trialjapan/licensing.aspx?culture=ja-JP
http://trial.trymicrosoftoffice.com/trialjapan/setupinfo.aspx?culture=ja-JP

http://www.forest.impress.co.jp/article/2008/10/17/ime2007update.html


まぁ、個人的にはATOK派なので、ATOKをお勧めするけど。

ATOKなら、体験版もあるし、DL販売もしてます。

http://www.atok.com/

又、OFFICE 2007には試用版があり、Office IME 2007も含まれています。
(WORD等の本体ソフトは試用版なので使用制限が存在するが、IME2007には制限が無い。)

http://trial.trymicrosoftoffice.com/trialjapan/default.aspx?re_ms=oo&culture=ja-JP
http://trial.trymicrosoftoffice.com/trialjapan/licensing.aspx?culture=ja-JP
http://trial.trymicrosoftoffice.com/trialjapan/setupinfo.aspx?culture=ja-JP

http://www...続きを読む

Qfreadでデータがない場合の読込値は?

あるバイナリデータからデータを読み込んでいます。

全てデータを読み込んだら、データの読み込みを終了させたいと考えています。

データの読み込んでいき、最後のデータの読み込み終了後、さらにデータを読み込むと\0を読み込むと考えたのですが、間違いでしょうか?
do~while();文を使った場合、()内には何を代入したらいいですか?

どうしてもわからなくて困っております.
ご存知の方がいましたら教えていただけないでしょうか?
よろしくお願いいたします.

Aベストアンサー

>データの読み込んでいき、最後のデータの読み込み終了後、さらにデータを読み込むと\0を読み込むと
>考えたのですが、間違いでしょうか?
最後に\0は読み込まれません。
freadは読み込んだ要素の数を返します。要素のサイズが1の場合は、読み込んだバイト数が返ることに
なります。そうすると、戻り値が0の場合が、読み込みの終わりと判断することになるのですが、
読み込み時、エラーがあった場合も、freadは0を返します。つまり、エラーなのかファイル終端なのかは、freadの戻り値だけでは、判断できません。従って、その後、feofを呼び出し、ファイル終端に達しているかを確認します。ファイル終端なら、正常終了、そうでないならエラーが発生していると、判断します。


>do~while();文を使った場合、()内には何を代入したらいいですか?
do whileでは難しいです。while(1)を使用したほうが、簡単に作れます。

上記を踏まえて、作成したサンプルが、以下の内容です。
ファイル名をsample.cとして、プログラムsampleを作成後、
sample xxx
(xxxは読み込みたいファイル名)とすると、
毎回、読み込んだファイルのサイズを出力し、正常であれば「正常終了」
が、表示されます。
-----------------------------------
#include <stdio.h>
#include <errno.h>
int main(int argc , char *argv[])
{
FILE*fp;
size_trsize;
intret;
charbuff[256];
if (argc != 2){
printf ("%s ファイル名\n",argv[0]);
return 0;
}
fp = fopen(argv[1],"rb");
if (fp == NULL){
printf("ファイルオープン失敗:errno=%d\n",errno);
return 10;
}
while(1){
rsize = fread(buff,1,sizeof(buff),fp);
//読み込んだ要素数が0なら終了
//但し、これはエラーが発生したから0なのか、ファイル終端に達したから0なのかを
//区別できない(freadの仕様のため)
if (rsize == 0) break;
//とにかく正常に読めたので、その処理をおこなう。
//読み込んだサイズはrsizeバイトである
//rsizeの内容を印字して、処理とする(実際の処理は質問者が実装する)
printf("rsize=%d\n",rsize);
}
//breakから抜けたとき、ファイル終端に達していることを確認する
if (feof(fp) == 0){
//ファイル終端に達していない、つまり何らかのエラーがあった
printf("ファイル読み込み失敗:errno=%d\n",errno);
//既にエラーが起こっているのでfcloseのエラーはチェックしない
fclose(fp);
return 10;
}
ret = fclose(fp);
if (ret != 0){
printf("ファイルクローズ失敗:errno=%d\n",errno);
return 10;
}
printf("正常終了\n");
return 0;
}

------------------------------------

>データの読み込んでいき、最後のデータの読み込み終了後、さらにデータを読み込むと\0を読み込むと
>考えたのですが、間違いでしょうか?
最後に\0は読み込まれません。
freadは読み込んだ要素の数を返します。要素のサイズが1の場合は、読み込んだバイト数が返ることに
なります。そうすると、戻り値が0の場合が、読み込みの終わりと判断することになるのですが、
読み込み時、エラーがあった場合も、freadは0を返します。つまり、エラーなのかファイル終端なのかは、freadの戻り値だけでは、判断できません...続きを読む

Q英語の長文の課題

私の行っている大学の英語の授業の課題が、教科書で2枚ほどの長文を訳して来いというものなんですが、私ははっきり言って英語が大の苦手で、ちょっと難しい文になるとちんぷんかんぷんになってしまいます。授業と課題についていけず、性能がいい翻訳ソフトを買おうと思ったんですが、あまり性能がいい翻訳ソフトは無い様で困ってしまいました。最も長文の訳しのサポートをしてくれる物ってなんなんでしょうか?教えてくださいお願いします。

Aベストアンサー

最も長文の訳しのサポートをしてくれるものはあなたです。
なにも課題はあなたの自由時間を束縛するために出されているのではなく、意味があって先生は出しています。
翻訳ソフトに逃げていると、ますます英語が苦手になります。
翻訳ソフトに逃げるのではなく、むしろ課題を踏み倒して野郎的な心構えをしてみてはどうでしょうか。私のように。



と、このままでは回答になっていない回答として通報されてしまいますので、あくまでアドバイスをば。

まず、訳してみる。
わけの分からない、これは絶対に訳せない! というものだけ、gooで聞いてみる。
ただ、「この文を訳してください」と言うのではなく、「that以下のtoが何を指定しているのか分かりません」など、具体的に。回答率も上がります。

英語は死ぬまでついてきます。がんばってください。

Qファイル読み込みとmap処理

Visual C++ 2008 Express Edition 環境です。

入力テキストファイルを読み込み、空白で単語を区切り、単語すべてをmapにいれるという処理のプログラムを書こうとしています。
perlでいうところのsplit, 配列へのpushをC++でstrtokとmapでならかけると思いました。

入力ファイルは
input1.txt---------------
cat dog mice human
mosquito beetle spider
-------------------------

プログラムは
#include <stdio.h>
#include<iostream>
#include <map>
#include <vector>

int main( )
{
FILE *input_file1;
input_file1 = fopen("input1.txt", "r");
char str[256];
char *token;
std::vector<char *> my_vector; //

while (fgets(str, 256, input_file1) != NULL) {
token = strtok( str , " " );
while( token != NULL ){

my_vector.push_back(token) ;
printf("%s\n",token);
token = strtok( NULL , " " );
}
}

printf("starting vector loop\n");

std::vector<char *>::iterator it = my_vector.begin(); //
while( it != my_vector.end() ) //
{
printf("%s\n",*it);
++it; //
}
fclose(input_file1);

return 0;
}

というふうにしました。

cat
dog
mice
human
mosquito
beetle
spider
というような出力がなされるものと思ったのですが、実行してみると
mapを使ったループ(全要素)出力は
mosquito
uito
le
mosquito
beetle
spider
というふうに出力されてしまいます。
strtokで単語を分ける部分は問題なく出力で確認できるので、問題はmapの作り方やポインタだと思うのですが原因がわかりません。

問題点、解決策がお分かりになる方、よろしくお願いします。

Visual C++ 2008 Express Edition 環境です。

入力テキストファイルを読み込み、空白で単語を区切り、単語すべてをmapにいれるという処理のプログラムを書こうとしています。
perlでいうところのsplit, 配列へのpushをC++でstrtokとmapでならかけると思いました。

入力ファイルは
input1.txt---------------
cat dog mice human
mosquito beetle spider
-------------------------

プログラムは
#include <stdio.h>
#include<iostream>
#include <map>
#include <vector>

int main( )
{
F...続きを読む

Aベストアンサー

map 関係ないですよね。

直接的な原因は strtok で得られたポインタが str 配列の位置を指しているので、行を読むたびに str の中身は書き換えられているためです。

ポインタを vector に入れるのではなくて、文字列をコピーして入れるように変更しましょう。

また、空白で区切られているなら、ファイルから ifstream を作成して
operator>> で読み込んだ方が楽だと思います。

Q本番測定を英語で何ていいますか?

ある無線機器の無線性能の測定をします。
試作品でトライアル測定をして、量産試作品で本番測定します。
トライアル測定は英語でtrial mesurementでいいかと思いますが、
本番測定は英語で何と表現すればいいか教えてください。

Aベストアンサー

「トライアル測定」と「本番測定」と云う日本語の内容を考え直してください。
トライアル測定=試作品に付いての測定(真剣で真面目な、記録も残る)。
本番測定=量産試作品に付いての測定(真剣で真面目で記録が残り、ユーザーにも報告される、
場合に依っては保証データともなる)。トライアルだから、測定が問題なく行くか測定してみようでは無いわけです。
本番だから、さあこれが終われば商品でお金を頂けますよと言うわけでもありません。
要するに「測定」です。「試作品」と「量産試作品」に付いての。
この点を念頭に置かれて、trial measurement 的な、補足説明が無いと判らない様な表現以外の表現を見つけてください。
ちなみに、コメントは
practical measurement = ???
オフィシャルトライアル=スキー滑降競技の本番前の公式コースを使った公式練習。
actual measurement =? 回答者はお気付きの様ですが。

現場で何気なく使っている言葉の翻訳では、まず日本語の吟味が必要です。

Q可変長構造体をファイルから読み込み処理

可変長の構造体、
typedef struct 構造体(仮)
{
char c1,c2;
float f1,f2;
double d;
int size;//↓strのサイズ
char str[1];//文字配列
}構造体(仮);

の形式で書かれたバイナリデータファイルがあります。

そのファイルを読み込んでcsv形式で出力する処理を、
ファイルからの読み込む回数を減らしてやりたいと思っています。

その方法を教えていただけませんか?
よろしくおねがいします。

Aベストアンサー

>mallocで取れるだけ領域を取ってそこからその
処理系や環境によりますがWindowsやLinuxの場合100Mぐらいは余裕でとれてしまいます。

>構造体の途中からfreadすることって可能でしょうか?
可能です。
memcpy( (char*)s+読み込んだバイト , pBuf , structSize - (読み込んだバイト) );
みたいな感じになります。
sizeを読み込んでから切れる場合と、sizeの前で切れる場合があるので
sizeの前で切れた場合は次のバッファを読み込んでから構造体のサイズを確定する処理
をする必要があるでしょう。

ただ構造体のalignmentには注意してください。
例えば
typedef struct _S{
char a;
short b;
}S;
の場合3バイトとは限りません。コンパイラの設定によっては
paddingの部分で切れる可能性も考慮する必要があります。

Qテレビでお勧めの英語ニュース

宜しくお願いします。
テレビのニュース番組で英語、日本語の切り替えができる番組を教えてください。
NHKの番組でもどれが該当するかわからず。。。

字幕放送、という情報が新聞に載っていますが、字幕全然でてこない。。。。

英語の音声を聴いている時に英語の字幕をだせるのでしょうか。。。

また、HDDに録画するときに、字幕や英語、日本語の切り替えができるように
録画することは可能でしょうか?
録画機の性能によって可能不可能があるのでしょうか。。。

教えてください。
宜しくお願いします。

Aベストアンサー

テレビは、日本人アナウンサーの声が英語に切り替えてもかすかにかぶったりして聞きづらいように思います。PCをお使いになれるのですから、PCを利用されたらどうでしょう?ケーブルテレビと契約する方法もあるのかもしれませんが・・・

☆NHK WORLD
http://www3.nhk.or.jp/nhkworld/
スクリプトもついていて利用しやすい物が多いです。ニュースですので多少スクリプトと違う場合もあります。

丁寧にNHK WORLDの英語を勉強するのであれば、以下のサイトから、「ニュースで英会話」をご利用になることをお勧めします。

☆NHK語学番組
http://www.nhk.or.jp/gogaku/

海外のニュースでしたら次のリンクサイトを利用してみて下さい。

☆英語のゆずりん
http://english.chakin.com/

「海外ニュース、英字新聞&ポッドキャスト」をクリックされるとたくさん利用できそうなサイトが紹介されます。しかし、スクリプトを利用したいのであれば「英語学習ESLサイト」等の方が利用できるものが多いかもしれません。その他にも役立つものが見つけられるサイトではないかと思います。

次のサイトは学習者向けなのでスクリプトが確実に利用できます。

☆VOA Special English
http://www.voanews.com/learningenglish/home/

最近はYouTubeを利用した次の様なサイトもあります。

☆EEvideo
http://www.eevideo.net/newsite1024/index.php

テレビは、日本人アナウンサーの声が英語に切り替えてもかすかにかぶったりして聞きづらいように思います。PCをお使いになれるのですから、PCを利用されたらどうでしょう?ケーブルテレビと契約する方法もあるのかもしれませんが・・・

☆NHK WORLD
http://www3.nhk.or.jp/nhkworld/
スクリプトもついていて利用しやすい物が多いです。ニュースですので多少スクリプトと違う場合もあります。

丁寧にNHK WORLDの英語を勉強するのであれば、以下のサイトから、「ニュースで英会話」をご利用になることをお勧めしま...続きを読む

Qファイルの読み込みとメモリ確保について。

ファイルから文字を読み込んで
それを配列に入れて辞書順にソートさせようとしています。
それで、ソート以前の問題なのですが、ファイルから文字列を読み込んで配列にいれようとするのですが、
buffを動的にメモリ確保してその配列に入れたいと考えているのですが、なぜか入ってくれません。
whileでファイルの終わりがくるまで一行ずつ読み込んで
それをsに入れていき、sをbuff[]の配列に順番にいれていこうとしているのですが・・・。

ファイルは
aaaa
aabc
dda
wer
zie
ced
sdfe
be

など適当な文字の並びです。

malloc関数で動的に確保したメモリはその後普通の配列と同様に使えるのではなかったのでしょうか?
なので普通にbuff[i]=s;といった処理で入れれると思ったのですが。

ファイルは一行の長さの最大が100で
行数が4000行あると仮定しています。
今は小さいファイルでテストしていますが。

以下ソースです。

#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
#define MAX_LINE 4000

main()
{
FILE *fp;
char *buff,s[MAX_SIZE];
int i;

fp=fopen("words.txt","r");

buff=(char*)malloc(sizeof(char)*MAX_LINE);

i=0;
while(fgets(s,MAX_SIZE-1,fp)!=NULL){
buff[i]=s;
printf("%s",buff[i]);
i++;
}
fclose(fp);
}

とりあえずファイルの内容を配列に入れないとソートできないので、配列に全て入れてしまいたいと考えています。

間違いがどこにあるのか指摘よろしくおねがいします。m(-_-)m

ファイルから文字を読み込んで
それを配列に入れて辞書順にソートさせようとしています。
それで、ソート以前の問題なのですが、ファイルから文字列を読み込んで配列にいれようとするのですが、
buffを動的にメモリ確保してその配列に入れたいと考えているのですが、なぜか入ってくれません。
whileでファイルの終わりがくるまで一行ずつ読み込んで
それをsに入れていき、sをbuff[]の配列に順番にいれていこうとしているのですが・・・。

ファイルは
aaaa
aabc
dda
wer
zie
ced
sdfe
be

など...続きを読む

Aベストアンサー

訂正と補足です。
半分寝ぼけて書いたコードなので最後のメモリの解放の部分が間違ってました。

> free( buff );

for( i = 0; i < MAX_LINE; i++ ){
free( buff[i] );
}
free( buff );

さて、まず問題はファイルから一行ずつ単語を読み込んでバッファへ保存しておき、
データをソートする。
その際にファイルから読み込んだ一行の単語を動的に用意した配列へうまく保存でき
ないということでしたね。順を追ってみていきましょう。

#define MAX_SIZE 100
#define MAX_LINE 4000

char *buff, s[MAX_SIZE];

まず、大前提として「C言語では文字列は char 型の配列で表す」ということがあり
ます。つまり、文字列データ型を標準ではサポートしてないのです。

確か、「ファイルから文字列を一行読み込んでそれを配列に保存する」ということを
したいんでしたね。
と、いうことはただ単に配列を用意するのではなく「文字列を格納する配列」の配列
を用意してやる必要があります。

#define MAX_SIZE 100
#define MAX_LINE 4000

char** buff;
char s[ MAX_SIZE ];

配列の配列のためのポインタ変数は「ポインタのポインタ」を用意してやります。
この変数へ文字列保存用へ確保したバッファのアドレスを入れてやるのです。

buff=(char*)malloc(sizeof(char)*MAX_LINE);

という風になっていますが、配列の配列を用意してやるので少し手順が変わってき
ます。

buff = ( char** )malloc( sizeof( char* ) * MAX_LINE );

まず、それぞれ確保する文字列バッファのアドレスを格納するためのポインタ配列
を確保してやります。

for( i = 0; i < MAX_LINE; i++ ){
buff[i] = ( char* )malloc( sizeof( char ) * MAX_SIZE );
}

その後に、それぞれのポインタに文字列のためのバッファへのアドレスを配列に保
存してやることで「文字配列の配列」が確保できるわけです。

確保したメモリは使い終わったらちゃんと解放してやる必要があります。さもない
とメモリリークの原因となってしまいますから。

具体的にどうするかというとメモリの確保と逆の手順を踏みます。

for( i = 0; i < MAX_LINE; i++ ){
free( buff[i] );
}

ポインタ配列に入っているそれぞれの文字列用のバッファを解放する。

free( buff );

最後にポインタ配列を解放する。

さて、次に文字列のコピーですが、先に述べた通りC言語では文字列をサポートし
ていません。

buff[i]=s;

なので、ただ単に代入するだけではコピーできません。

for( j = 0; j < MAX_LINE; j++ ){
for( i = 0; i < MAX_SIZE; i++ ){
buff[j][i] = s[i];
}
}

このようにする必要があります。が、標準関数に文字列をコピーする関数が用意さ
れていますのでそれを使いましょう。

その関数は string.h で定義されている strcpy 関数や stdio.h 出て異議されて
いる sprintf 関数です。

sprintf 関数のほうが何かと使い勝手がいいのでこれを使います。

sprintf( buff[i], "%s", s );

この関数は printf 関数と同様にコンソール画面ではなくバッファへ文字列を出力
してくれます。

以上を踏まえたコードが先に投稿したソースです。


さて、ここでは単語の配列を文字配列の配列で扱いましたが、コードが結構うざく
なったりします。

そんなときは文字配列を構造体として扱うとすっきりするかと思います。

#define MAX_SIZE 100

typedef struct {
char str[ MAX_SIZE ];
} WORDS;

WORDS* buf;
buf = ( WORDS* )malloc( sizeof( WORDS ) * MAX_LINE );

sprintf( buf[i].str, "%s", str );

一応サンプルコードを提示しておきます。

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100
#define MAX_LINE 4000

typedef struct {
char str[ MAX_SIZE ];
} WORDS;

int main(void){
FILE* fp;
WORDS* buf;
char str[ MAX_SIZE ];
int i;

if( ( fp = fopen( "words.txt", "r" ) ) == NULL ){
return -1;
}

buf = ( WORDS* )malloc( sizeof( WORDS ) * MAX_LINE );

for( i = 0; i < MAX_LINE; i++ ){
if( fgets( str, MAX_SIZE - 1, fp ) == NULL ){
break;
}
sprintf( buf[i].str, "%s", str );
printf( "%s", buf[i].str );
}

free( buf );
fclose( fp );

return 0;
}

訂正と補足です。
半分寝ぼけて書いたコードなので最後のメモリの解放の部分が間違ってました。

> free( buff );

for( i = 0; i < MAX_LINE; i++ ){
free( buff[i] );
}
free( buff );

さて、まず問題はファイルから一行ずつ単語を読み込んでバッファへ保存しておき、
データをソートする。
その際にファイルから読み込んだ一行の単語を動的に用意した配列へうまく保存でき
ないということでしたね。順を追ってみていきましょう。

#define MAX_SIZE 100
#define MAX_LINE 4000

char *buff,...続きを読む


人気Q&Aランキング

おすすめ情報