4

私はファイルにいくつかのバイトを書き込むためにこのようなプログラムを書いています。

#include <fstream>

int main()
{
    char buffer[4] = {0, 0, 255, 255};
    std::ofstream f("foo.txt", std::ios_base::binary);
    f.write(buffer, sizeof buffer);
    f.close();
    return 0;
}

これは正常に機能し、システムで期待される結果が得られます。

$ g++ -std=c++11 -pedantic -Wall -Wextra signedness.cc
$ ./a.out
$ cat foo.txt
$ od -t x1 foo.txt 
0000000 00 00 ff ff
0000004

同等のCコードは次のようになります。

#include <stdio.h>

int main()
{
    char buffer[4] = {0, 0, 255, 255};
    FILE *f = fopen("bar.txt", "wb");
    fwrite(buffer, sizeof *buffer, sizeof buffer, f);
    fclose(f);
    return 0;
}

このプログラムも正常に動作し、システムで期待される出力を提供します。

上記のバイトのファイルへの書き込み方法が問題ないかどうか知りたいです。

C ++ n3242.pdfのセクション4.7(積分変換)は、ポイント3で言及しています。

宛先タイプが署名されている場合、宛先タイプ(およびビットフィールド幅)で表すことができれば、値は変更されません。それ以外の場合、値は実装定義です。

C n1256.pdfのセクション6.3.1.3(符号付きおよび符号なし整数)は、ポイント3で言及しています。

それ以外の場合、新しいタイプは署名され、値を表すことができません。結果が実装定義であるか、実装定義のシグナルが発生します。

char buffer[4]これらの抜粋から、 255を型で表すことができないため、255を最後の2バイトとして割り当てると、プログラムが実装定義の動作を呼び出すように見えますchar。私がこれについて正しければ、これらの4バイトをファイルに書き込む正しい方法は何でしょうか?タイプをbufferからcharに変更unsigned charしても、C ++では役に立たないようです。これは、ストリームのwrite()関数がまだタイプの最初のパラメーターを想定しているためconst char*です。

4

3 に答える 3

5

Remember that ofstream is just a typedef for std::basic_ofstream<char>.

When you don't want things being treated as char, just use std::basic_ofstream<unsigned char> or std::basic_ofstream<uint8_t>.

Ultimately, though, iostreams are made for formatted I/O. The API is horrible for binary I/O (since it doesn't take void*) and also incredibly slow. Furthermore, every character is converted by a "facet", making it hard to guarantee 1:1 correspondence between input bytes and bytes on disk. basic_filebuf is a little better, but not much. Using fopen and fwrite is still a perfectly valid approach, even in C++.

于 2012-09-17T22:25:12.530 に答える
0

確かに、255 は符号付きの型で表すことはできませんが、255 をchar割り当てているのではなく、 を割り当てている を割り当てていFFます-1

uint8_tで定義されている を使用するstdint.hか、少なくとも を使用しunsigned charます。

于 2012-09-17T21:51:59.203 に答える
-1

「実装定義」は、C++ の国際標準の言語であり、考えられるすべてのケースを網羅することを目的とした準法的文書です。

そのため、char が 9 ビットのマシンで実行されている可能性があるため、バイナリ データとファイルを処理するという行為には、いくつかの側面が実装によって定義されることが内在しています。標準の文字により、各ターゲットマシンのドキュメントを調べて、必要な動作がそれぞれの場合に達成されることを確認する必要があります.

現実の世界では、最新の汎用 CPU はすべて 8 ビットのバイトを持ち、2 の補数演算を使用するため、非常に特殊な状況をターゲットにしている場合を除き、心配する必要はありません。

于 2012-09-17T22:19:56.313 に答える