長いテキストファイルを
1行読み込み、その1行を削除(空白で埋めるも可)
そして次の行・・。
をファイルの最後まで繰り返す。
http://www.kumei.ne.jp/c_lang/index_c.html
�b������INDEX
可能です。
上のページの第18章あたりを参考にしてください。
http://www.linux.or.jp/JM/html/LDP_man-pages/man2/truncate.2.htm...
Manpage of TRUNCATE
結局、ファイル自体は残したままファイルの中身を全部削除したいということでしょうか?
であれば、UNIX系であれば、
truncate(”aaa”,0);
とかで、aaaというファイルの中身は全部消えます。
truncate()が使えなければ、
FILE *fp = fopen(”aaa”,”w”);
fclose(fp);
とかで、上書きモードでopenしてすぐにcloseすればできるような気がしますが。
やりたいこと自体が違うのかな?
http://www.hatena.ne.jp/1120842807#
人力検索はてな - C言語で次のような事は可能でしょうか 長いテキストファイルを 1行読み込み、その1行を削除(空白で埋めるも可) そして次の行・・。 をファイルの最後まで繰り返す。..
空白で埋めるも可であるなら、
1行読み込んだバッファにmemsetなどで
空白入れて書き込むとか。
NULLセットして書き込むとかで良いのでは?
C++ならreplaceしちゃうとかで。
そのやり方が分からないんですよね。
サンプルソースとかある場所分かりませんかねぇ
Hoge Lumber Company
ダミーです。
行を削除というのは、行の先頭に改行があるようにすることですよね。
だったら
getc なり fgetc かなんか使って行の数を数えて
同じ数だけ改行を出力すればよいのではないでしょうか。
下記のソースでテキストファイルが空白に置き換えられません。
理由が分かる方いましたら、よろしくお願いします。
FILE * fp = fopen(”C:¥¥0.txt”,”r+”);
char szStrRcpt[1024];
while( fgets(szStrRcpt, sizeof(szStrRcpt), fp ) )
{
memset(szStrRcpt,’¥0’, sizeof(szStrRcpt));
fputs(szStrRcpt, fp);
}
fclose(fp);
return;
ftell()で今読む所を得て、編集。rewind(),fseek()して、fwrite()、またfseek()で出来ますが...
http://www.microsoft.com/japan/msdn/library/default.asp?url=/jap...
MSDN ライブラリ サイト移行に関する重要なお知らせ
標準C関数を使うならftell()とfseek()で読み込んだ後、行の先頭にファイルポインタを戻してから書き込みでしょうね。
エラー処理とか全部はしょってますが、下記のコードでWindowsXP+lccwin32(フリーのコンパイラ)でだいたい想定どおりに動きました
読み出した行の内容を行番号付きで表示しながら空白を書き込みます。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char *argv[])
{
FILE *fp;
long posi1,posi2;
int linelen;
int linenum = 1;
char buffer[1024];
/* ファイルをRead/Writeモードでopen */
fp = fopen(argv[1],”r+b”);
while(1){
/* 行先頭のファイル位置を取得 */
posi1 = ftell(fp);
/* 1行読み込み */
if(fgets(buffer,1023,fp) == NULL){
break;
}
/* 次の行の先頭のファイル位置を取得 */
posi2 = ftell(fp);
/* 読み込んだ行を表示 */
printf(”LINE%05d: %s”,linenum,buffer);
linelen = strlen(buffer);
/* 読み込んだ行を空白で埋める */
if(linelen > 1){
memset(buffer,’ ’,linelen - 1);
}
/* 行先頭のファイル位置をシーク */
fseek(fp,posi1,SEEK_SET);
/* 空白で埋めた行を出力 */
fputs(buffer,fp);
/* 次の行の先頭のファイル位置をシーク
...これは要らない気がするが..
WindowsXP + lccwin32ではこれが 無いと動かない */
fseek(fp,posi2,SEEK_SET);
linenum++;
}
fclose(fp);
return 0;
}
http://133.64.170.129/JM/html/LDP_man-pages/man3/fseek.3.html
Manpage of FSEEK
FILE *fp;
char rbuf[BUF_SIZE];
char wbuf[BUF_SIZE];
int i = 0;
long line_head = 0, line_end = 0;
fp = fopen(”test.txt”, ”r+”);
if(fp){
while(1){
line_head = ftell(fp);
if(fgets(rbuf, BUF_SIZE, fp) == NULL){
exit(0);
}
line_end = ftell(fp);
wbuf[0] = ’¥0’;
for(i = 0; i < line_end-line_head-1; i++){
sprintf(wbuf, ”%s*”, wbuf);
}
sprintf(wbuf, ”%s¥n”, wbuf);
printf(”%s”, wbuf);
if(fseek(fp, line_head, SEEK_SET) == 0){
fputs(wbuf, fp);
}
}
上記のプログラムで、読み込んだ行の文字の分だけ ’*’をファイルに書き出します。
’*’をスペースにすれば、ファイルを空白で埋めることも可能です。
Vine 3.1 で動作確認しました。
「空白で置き換えられない」のなら、具体的にどうなってしまうのでしょうか?それをどうやって確認していますか(テキストエディタで確認している、とか)。
空白で埋めたいのなら、
memset(szStrRcpt,’¥0’, sizeof(szStrRcpt));
ではなく
memset(szStrRcpt,’ ’, sizeof(szStrRcpt));
ですけれど。
なにも変化がありません。
テキストエディタで確認しました。
また、そのように変更しましたが、結果変わりませんでした
>下記のソースでテキストファイルが空白に置き換えられません。
>理由が分かる方いましたら、よろしくお願いします。
ソースのおかしい場所を修正しておきました
FILE *fp = fopen("test.txt","r+");
char szStrRcpt[1024];
int p=0;//ファイルポインタの保存
while( fgets(szStrRcpt, sizeof(szStrRcpt), fp ) )
{
// memset(szStrRcpt,’¥0’, sizeof(szStrRcpt));
//まず、NULL文字で埋めるとテキストファイルは開けなくなってしまいますからスペースなどで
//つぶす方がいいでしょう、あと sizeof(szStrRcpt)にすると読み込んだバイトに関係なく1024
//バイトつぶされるので書き込むとそれ以降のデータがつぶされてしまいます
//ここはstrlenを使います、読み込んだデータはテキストなので最後に改行コードが入っている
//はずですから1ばいと引いておきます
if(*szStrRcpt)
memset(szStrRcpt,0x20, strlen(szStrRcpt)-1);
fseek(fp,p,SEEK_SET);
// そのままfputsすると読んだ後ろに書き込んでしまうことになります
// 読んだ後、読み込んだ分fseekでファイルポインタを戻さないと上書きできません
fputs(szStrRcpt, fp);
p=ftell(fp);
fseek(fp,p,SEEK_SET);
//書き込みをするとそこをファイル終端にされてしまうのでftell/fseekで再定義しなおします
}
fclose(fp);
return;
置換の場合は、上のように簡単にできますが、ANSI-Cで行削除の場合は、ファイルサイズが変わってしまうので、別のファイル(テンポラリ)に書き込んだ後、そのファイルをコピーした方がよいです
http://www.hatena.ne.jp/1120842807
人力検索はてな - C言語で次のような事は可能でしょうか 長いテキストファイルを 1行読み込み、その1行を削除(空白で埋めるも可) そして次の行・・。 をファイルの最後まで繰り返す。..
空白で埋めたいのなら、
memset(szStrRcpt,’¥0’, sizeof(szStrRcpt));
ではなく
memset(szStrRcpt,’ ’, strlen(szStrRcpt));
です。
これで改行も全部空白になるはずですが?
なお実際の変化はクローズした後、場合によってはそのソフトが終了してからでないと反映されないかも。
すみません、もう一点大事なこと忘れてました。
と言うか、7番目の人が書いてるからいいか(笑
つまり、fgets した時点でポインター進んでますので、戻してから fputs してやらないとダメです。
ただ、普通の処理的に言うと、こういう読みながら上書きする処理はあまりお勧めは出来ません。普通は別ファイルに書き出して、クローズしてから元のファイルを消してリネームってやります。
1行づつ読み込んで処理をしたいのです。
そして読み込んだ行がわかる様に、その行を削除(もしくは空白で埋める)をしたいと思っています。