C言語関係掲示板

過去ログ

No896 ファイルに追加モードで書き込みながら、最後の改行コードを取り除く

[戻る] [ホームページ]
No.570

追加モードでのfseekについて
投稿者---サエキ(2003/10/24 16:56:41)


サエキといいます。

ファイルに追加モードで書き込みながら、
ファイル最後の改行コードを取り除くという
コードは、どのように書いたら、いいですか?


sample.cでは、
ファイルポインタの位置を変更しても書き込みが始まるのは、次の行からです。

FAQを探しましたが、
新規にファイルを作成する方法しか、
載っていませんでした。
まだFAQの方にも同じ質問がありましたら、番号を教えて下さい。


sample.c---------------------------
#include<stdio.h>
#include<stdlib.h>
void main()
{
FILE *fp;
fp=fopen("txt.txt", "a");
fprintf(fp, "[aaaaaaaaaaaa]");
fprintf(fp, "[bbbbbbbbbbbbb]");
fprintf(fp, "[cccccccccccc]\n");
fseek(fp, -2, SEEK_END);
fprintf(fp, "[ddddddddddddd]\n");
fclose(fp);

return;
}
-------------------------------
現状:
[aaaaaaaaaaaa][bbbbbbbbbbbbb][cccccccccccc]
[ddddddddddddd]
-------------------------------
やりたいこと:
[aaaaaaaaaaaa][bbbbbbbbbbbbb][cccccccccccc][ddddddddddddd]
-------------------------------


No.571

Re:追加モードでのfseekについて
投稿者---かずま(2003/10/24 19:22:27)


【掲示板ご利用上の注意】
・ソースを添付する際にはHTML変換ツールで字下げしてください。 
#include <stdio.h>

#define FILENAME  "txt.txt"

int main(void)
{
    FILE *fp;

    if ((fp = fopen(FILENAME, "r+")) == NULL &&
        (fp = fopen(FILENAME, "w")) == NULL) return 1;
    fseek(fp, 0, SEEK_END);

    fprintf(fp, "[aaaaaaaaaaaa]");
    fprintf(fp, "[bbbbbbbbbbbbb]");
    fprintf(fp, "[cccccccccccc]\n");
    fseek(fp, -2, SEEK_END);
    fprintf(fp, "[ddddddddddddd]\n");
    fclose(fp);

    return 0;
}


No.572

Re:追加モードでのfseekについて
投稿者---YuO(2003/10/24 19:27:05)


ソースを書く場合は,【掲示板ご利用上の注意】に記述されている方法でソースを記述して下さい。
インデントが潰れて読みにくいです。


>ファイルに追加モードで書き込みながら、
>ファイル最後の改行コードを取り除くという
>コードは、どのように書いたら、いいですか?
>FAQを探しましたが、
>新規にファイルを作成する方法しか、
>載っていませんでした。

テキスト形式の場合,それが一番効率がよいです。

ファイルをテキスト形式で開く場合,
最後の改行コードを上書きするプログラムは,
効率を全く無視したプログラムになります。
#末尾に記述しました。


    fp=fopen("txt.txt", "a");


Append-Modeは常にファイル末尾に追記します。
ファイルを書き換える場合には,"r+"を利用します。


    fseek(fp, -2, SEEK_END);


これはファイルをテキストモードで開いている以上,
常に未定義動作となります。

テキストモードで開いたファイルに対してfseekを利用する場合,
・第二引数が0
・第二引数が以前に同一のストリームに対して実行したftellの戻り値で,第三引数がSEEK_END
の何れかでなければいけません。


以下,とりあえず最後の改行を潰して追記するサンプルです。
手元の環境(Borland C++ Compiler 5.5.1 on Windows NT 4.0)では問題なく動きましたし,
未定義/未規定/処理系依存の動作はできる限り潰したつもりですが,
全ての環境で動くことは保証しません。
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char * argv[])
{
    FILE * fp;
    fpos_t pos, pos_cur;
    int c;

    if (argc != 2) {
        fprintf(stderr, "The \"argc\" parameter must be 2.\n");
        return EXIT_FAILURE;
    }
    /* ファイルを開く */
    if ((fp = fopen(argv[1], "r+")) == NULL) {
        fprintf(stderr, "File open error.\n");
        return EXIT_FAILURE;
    }

    /* 最後の改行位置を探す */
    fgetpos(fp, &pos);
    while (fgetpos(fp, &pos_cur), (c = fgetc(fp)) != EOF) {
        if (c != '\n') continue;
        pos = pos_cur;
    }
    /* 最後の改行位置に現在位置を移動する */
    fsetpos(fp, &pos);

    /* 追加内容を出力する */
    fprintf(fp, "[ddddddddddddd]\n");

    /* ファイルを閉じる */
    fclose(fp);

    return EXIT_SUCCESS;
}



No.579

Re:追加モードでのfseekについて
投稿者---サエキ(2003/10/27 10:53:27)


>ソースを書く場合は,【掲示板ご利用上の注意】に記述されている方法でソースを記述して下さい。
>インデントが潰れて読みにくいです。
すみません。
以後、ツールを使って字下げをし、
投稿するよう気をつけます。


かずまさん、YuOさん>
本当にありがとうございました。
VC6.0の環境の方で動作を確認しました。