1

テキストファイルを読み込んで、その内容をCの別のテキストファイルに転送したいのですが、私のコードは次のとおりです:

             char buffer[100]; 

             FILE*  rfile=fopen ("myfile.txt","r+");
             if(rfile==NULL)
            {
              printf("couldn't open File...\n");
            }


            fseek(rfile, 0, SEEK_END);
            size_t file_size = ftell(rfile);
            printf("%d\n",file_size);
            fseek(rfile,0,SEEK_SET);
            fread(buffer,file_size,1,rfile);


            FILE* pFile = fopen ( "newfile.txt" , "w+" );
            fwrite (buffer , 1 ,sizeof(buffer) , pFile );
            fclose(rfile);
            fclose (pFile);
            return 0;
          } 

私が直面している問題は、受信ファイルに不要なデータが表示されることです。「sizeof(buffer)」と「file_size」の両方で fwrite 関数を試しましたが、最初のケースでは、受信中に無駄な文字が多く表示されます。 2 番目のケースでは、役に立たない文字の数は 3 つしかありません。誰かが私の間違いを指摘し、これらの役に立たない文字を取り除く方法を教えていただければ幸いです...

4

5 に答える 5

3

buffer受信ファイルに (100 文字) のすべての内容を書き込んでいます。読み取ったデータの正確な量を書き込む必要があります。

fwrite(buffer, 1, file_size, pFile)

コードにチェックを追加する:

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

#define BUFFER_SIZE   100

int main(void) {
    char buffer[BUFFER_SIZE]; 
    size_t file_size;
    size_t ret;

    FILE* rfile = fopen("input.txt","r+");
    if(rfile==NULL)
    {
      printf("couldn't open File \n");
      return 0;
    }

    fseek(rfile, 0, SEEK_END);
    file_size = ftell(rfile);
    fseek(rfile,0,SEEK_SET);

    printf("File size: %d\n",file_size);

    if(!file_size) {
        printf("Warring! Empty input file!\n");
    } else if( file_size >= BUFFER_SIZE ){
        printf("Warring! File size greater than %d. File will be truncated!\n", BUFFER_SIZE);
        file_size = BUFFER_SIZE;
    }

    ret = fread(buffer, sizeof(char), file_size, rfile);
    if(file_size != ret) {
        printf("I/O error\n");
    } else {
        FILE* pFile = fopen ( "newfile.txt" , "w+" );
        if(!pFile) {
            printf("Can not create the destination file\n");
        } else {
            ret = fwrite (buffer , 1 ,file_size , pFile );
            if(ret != file_size) {
                printf("Writing error!");
            }
            fclose (pFile);
        }
    }
    fclose(rfile);
    return 0;
}
于 2013-04-10T06:23:03.227 に答える
2

fseek()、 、fread()およびのすべての呼び出しからの戻り値を確認する必要がありfwrite()ますfclose()

あなたの例でfread()は、100 バイト長の 1 ブロックを読み取りました。多くの場合、次のようにパラメーターを逆にすることをお勧めします ret = fread(buffer,1,file_size,rfile)。値はret、完全なブロックを読み取れなかったと言うだけでなく、読み取ることができたバイト数を示します。

于 2013-04-10T06:21:48.347 に答える
1

(ほぼ) 汎用のファイル コピー関数の実装を次に示します。

void fcopy(FILE *f_src, FILE *f_dst)
{
    char            buffer[BUFSIZ];
    size_t          n;

    while ((n = fread(buffer, sizeof(char), sizeof(buffer), f_src)) > 0)
    {
        if (fwrite(buffer, sizeof(char), n, f_dst) != n)
            err_syserr("write failed\n");
    }
}

f_src読み取り用の開いているファイル ストリームと、書き込み用の別の開いているファイル ストリームをf_dst指定すると、 に関連付けられたファイル (の残り) を に関連付けられたファイルにコピーしf_srcますf_dstBUFSIZからのバッファ サイズを使用して、適度に経済的にこれを行い<stdio.h>ます。多くの場合、バッファーを大きくすると (4 KiB または 4096 バイト、さらには 64 KiB または 65536 バイト)、パフォーマンスが向上します。64 KiB を超えてもほとんどメリットはありませんが、YMMV.

上記のコードはerr_syserr()、戻らないと想定されているエラー報告関数 ( ) を呼び出します。そのため、「ほぼ汎用」と指定しました。この関数は、値を返すようにアップグレードできますint。成功すると 0、失敗すると EOFを返します。

enum { BUFFER_SIZE = 4096 };

int fcopy(FILE *f_src, FILE *f_dst)
{
    char            buffer[BUFFER_SIZE];
    size_t          n;

    while ((n = fread(buffer, sizeof(char), sizeof(buffer), f_src)) > 0)
    {
        if (fwrite(buffer, sizeof(char), n, f_dst) != n)
            return EOF;  // Optionally report write failure
    }
    if (ferror(f_src) || ferror(f_dst))
        return EOF;  // Optionally report I/O error detected
    return 0;
}

この設計では、ファイルを開いたり閉じたりしないことに注意してください。開いているファイル ストリームで動作します。ファイルを開き、コピー関数を呼び出す (または関数にコピー コードを含める) ラッパーを作成できます。また、バッファー サイズを変更するには、バッファー定義を変更するだけです。メインのコピーコードは変更していません。また、この小さな関数を呼び出す際の「関数呼び出しのオーバーヘッド」は、I/O 操作自体のオーバーヘッドによって完全に圧倒されることに注意してください。

于 2013-04-10T16:04:25.190 に答える
0

Noteはではなく をftell返します。ただし、ここでは問題にしないでください。ただし、それ自体は必ずしもバイトオフセットではありません。標準では、 に対する許容可能な引数であることのみを要求しています。からより良い結果が得られるかもしれませんが、標準による仕様の欠如から、同じ移植性の問題があります。(自白:私は標準自体をチェックしませんでした;これはすべてマンページから入手しました。)longsize_tftellfseekfgetpos

ファイルサイズを取得するより確実な方法は、fstat.

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd>

struct stat stat_buf;
if (fstat(filename, &buf) == -1)
    perror(filename), exit(EXIT_FAILURE);
file_size = statbuf.st_size;
于 2013-04-10T06:30:34.440 に答える