0

ファイルを作成してデータを書き込んだ後、ファイルのサイズを取得しようとしています。実際のファイル サイズに対応していないように見える値を取得します。これが私のプログラムです。ファイル サイズをビット、バイト、キロバイト、メガバイトで表示する方法を教えてください。私によると、ファイル サイズは 288 ビット、36 バイト、0.03515626 キロバイト、および 0.000034332 メガバイトである必要があります。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h> 
#include <sys/types.h> 
#define PERMS 0777

int main(int argc, char *argv[])
{
    int createDescriptor;
    int openDescriptor;

    char fileName[15]="Filename1.txt";
    umask(0000);

    if ((openDescriptor = creat(fileName, PERMS )) == -1)
    {
        printf("Error creating %s", fileName);
        exit(EXIT_FAILURE);
    }


    if(write(openDescriptor,"This will be output to testfile.txt\n",36 ) != 36)
    {
        write(2,"There was an error writing to testfile.txt\n",43);
        return 1;
    }

    if((close(openDescriptor))==-1)
    {
        write(2, "Error closing file.\n", 19);
    }
    struct stat buf;
    fstat(openDescriptor, &buf);
    int size=buf.st_size;
    printf("%d\n",size);
    printf("%u\n",size);

    return 0;
}
4

1 に答える 1

7

fstat()関数に戻りコードがあります。チェックしてください。

int r = fstat(openDescriptor, &buf);
if (r) {
    fprintf(stderr, "error: fstat: %s\n", strerror(errno));
    exit(1);
}

これは印刷されます:

エラー: fstat: ファイル記述子が正しくありません

うん...ファイル記述子を閉じました。これはもはやファイル記述子ではありません。fstat()を呼び出す前に行う必要がありclose()ます。

コードが気になります。

これは非常に壊れやすく、どのような状況でも推奨できません。

if (write(openDescriptor,"This will be output to testfile.txt\n",36 ) != 36)

あなたはこれを行うことができます:

const char *str = "This will be output to testfile.txt\n";
if (write(fd, str, strlen(str)) != strlen(str))

これは同じマシン コードにコンパイルされ、明らかに正しいものです (文字列内の文字数を数えて正しいかどうかを判断する必要がある元のコードとは対照的に)。

さらに良いことに、 をstderr使用している場合は、標準<stdio.h>関数を使用してください。

fprintf(stderr, "There was an error writing to %s: %s\n",
        fileName, strerror(errno));

定義時に同じエラーが表示されfileNameます...

// You should never have to know how to count higher than 4 to figure
// out if code is correct...
char fileName[15]="Filename1.txt";

// Do this instead...
static const char fileName[] = "Filename1.txt";

今回は実際にカウントを間違えた[15]はず[14]ですが、コンパイラに任せたほうがよいでしょう。コンパイラーにはおそらくより良いことがないので、コンパイラーの仕事を簡単にすることには何のメリットもありません。

マシンコードについて:

$ cat teststr.c
#include <unistd.h>
void func(int openDescriptor) {
    write(openDescriptor,"これがtestfile.txtに出力されます\n",36 );
}
$ 猫 teststr2.c
#include <string.h>
#include <unistd.h>
void func(int openDescriptor) {
    const char *str = "これは testfile.txt に出力されます\n";
    書き込み (openDescriptor, str, strlen(str));
}
$ cc -S -O2 teststr.c
$ cc -S -O2 teststr2.c
$ diff teststr.s teststr2.s
1c1
< .file "teststr.c"
---
> .file "teststr2.c"

うん。示されているように、 への呼び出しstrlen()は、実際には異なるマシン コードにはなりません。

于 2013-01-01T23:52:33.400 に答える