C ++ (Visual Studio), Не можете записать число 10 в файл, все остальные числа работают? - PullRequest
4 голосов
/ 11 февраля 2011

У меня тут какая-то странная проблема! Я пытаюсь написать таблицу цветов для 8-битного файла Windows 3.x. Я просто хочу, чтобы файл был в оттенках серого, поэтому я пытаюсь написать bbb0, ggg0, rrr0 256 раз, где r = g = b = 1..256

//write greyscale color table
for (int i = 255; i >= 0; i--) {
    writeS = (unsigned short)i;
    outfile.write ((char*)&writeS,sizeof(char)); // b
    outfile.write ((char*)&writeS,sizeof(char)); // g
    outfile.write ((char*)&writeS,sizeof(char)); // r
    writeS = 0;
    outfile.write ((char*)&writeS,sizeof(char)); // 0
}

Когда я смотрю на вывод, который получаю с помощью шестнадцатеричного редактора, все выглядит нормально, пока я не доберусь до числа 10, которое написано так:

... 0C 0C 0C 00 0B 0B 0B 00 0D 0A 0D 0A 0D 0A 00 09 09 09 00 08 08 08 00 ...

вместо:

... 0C 0C 0C 00 0B 0B 0B 00 0A 0A 0A 00 09 09 09 00 08 08 08 00 ...

Так что странно, что он делает это только с этим одним числом, но что еще удивительнее, это то, что когда я изменяю код, чтобы пропустить число 10 и вместо этого пишу 9, это работает.

//write greyscale color table
for (int i = 255; i >= 0; i--) {
    writeS = (unsigned short)i;
    if (writeS == 10) writeS = 9;
    outfile.write ((char*)&writeS,sizeof(char)); // b
    outfile.write ((char*)&writeS,sizeof(char)); // g
    outfile.write ((char*)&writeS,sizeof(char)); // r
    writeS = 0;
    outfile.write ((char*)&writeS,sizeof(char)); // 0
}

дает:

... 0C 0C 0C 00 0B 0B 0B 00 09 09 09 00 09 09 09 00 08 08 08 00 ...

Есть ли что-то странное, что происходит с нотацией? Есть ли очевидные ошибки, которые я пропустил? Кто-нибудь сталкивался с чем-то подобным раньше? Спасибо!

Ответы [ 4 ]

14 голосов
/ 11 февраля 2011

«Число 10» в ASCII - это символ перевода строки, \n.В C ++ это символ новой строки.

Вы, очевидно, открыли файл как текстовый поток.Поскольку переводы строк по-разному представлены на разных платформах, текстовые потоки выполняют перевод строк: при чтении они переводят представление новой строки для конкретной платформы в \n, а при записи переводят символ \n в представление новой строки для конкретной платформы.

В Windows разрывы строк представлены \r\n.Когда вы записываете \n в текстовый поток, он записывается как \r\n.

Чтобы записать необработанные двоичные данные, вам необходимо открыть поток как двоичный поток.Это делается путем передачи флага ios_base::binary в конструктор потока.

1 голос
/ 11 февраля 2011

Причина, по которой это происходит, в том, что вы, вероятно, не открываете файл в двоичном режиме.При открытии файла в обычном (текстовом) режиме в Windows каждый раз, когда вы пишете символ новой строки (который имеет числовое значение 10), поток преобразует его в \ r \ n, что объясняет, почему вы видите дополнительные байтыпри записи числа 10.

Чтобы это исправить, откройте файл в двоичном режиме:

outfile.open(filename, ios::binary);

Надеюсь, это поможет!

1 голос
/ 11 февраля 2011

Символ номер 10 - это символ перевода строки, который преобразуется в комбинацию CRLF (13 + 10), если файл открывается в текстовом режиме в Windows. Откройте файл в двоичном режиме.

0 голосов
/ 11 февраля 2011

Существует большая разница между двоичным и текстовым, как сказали выше люди. 10 будут испорчены в потоке и будут пропущены / лишние байты.

Открыть в двоичном виде!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...