Ответ 1
0A - символ подачи строки, а 0D - возврат каретки. Обычно они связаны с текстовым режимом.
Вы открыли файл в двоичном режиме? (например, fopen("foo.txt", "wb"
))
У меня есть эта странная проблема:
Я пишу 16 символов в двоичный файл, а затем пишу 3 целых числа, но когда я открываю свой файл с помощью некоторого средства просмотра двоичных файлов, я вижу добавленный дополнительный байт (что равно 0x0D).
Здесь мой код:
for(i = 0; i < 16; i++)
{
if(i < strlen(inputStr))
{
myCharBuf[0] = inputStr[i];
}
else
{
myCharBuf[0] = 0;
}
fwrite(myCharBuf, sizeof(char), 1, myFile);
}
myIntBuf[0] = inputNumber1;
fwrite(myIntBuf, sizeof(int), 1 ,myFile);
myIntBuf[0] = inputNumber2;
fwrite(myIntBuf, sizeof(int), 1 ,myFile);
myIntBuf[0] = inputNumber3;
fwrite(myIntBuf, sizeof(int), 1 ,myFile);
Я получаю следующие байтовые значения:
61 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0D 0A 00 00 00 05 00 00 00 08 00 00 00
Когда я ожидаю:
61 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0A 00 00 00 05 00 00 00 08 00 00 00
Есть ли у кого-нибудь идея, почему это может случиться?
0A - символ подачи строки, а 0D - возврат каретки. Обычно они связаны с текстовым режимом.
Вы открыли файл в двоичном режиме? (например, fopen("foo.txt", "wb"
))
Когда вы открываете файл, откройте для записи как двоичный "wb"
:
fopen(filename, "wb");
Когда вы открываете в текстовом режиме, происходит перевод Line Feeds (0A
) и возврат каретки (0D
).
fopen
файл в двоичном режиме с "wb".
fopen(filename, "wb");
в противном случае код в библиотеке будет выполнять автоматический перевод конца строки (на окнах вы на Windows, не правда ли?, что означает перевод '\n'
в '\r' '\n'
).
MS-DOS (и так сегодня с Windows) при записи файла в текстовом режиме добавляет 0x0D перед каждым 0x0A. Другими словами, он обрабатывает произвольные потоки данных по мере их поступления и из хранилища и беспорядок с их данными - совершенно безумно.
Откройте файл в двоичном режиме для безумной обработки.
Я считаю, что ваша переменная inputStr содержит символ новой строки и записывается в двоичный файл как возврат каретки и linefeed - двоичный '0D', за которым следует '0A'.
Например, следующая программа записывает 16 символов и 3 числа следующим образом.
FILE *fp;
fp = fopen("sample.bin", "wb+");
if(fp == NULL)
{
printf("Cannot create a file\n");
return;
}
int i;
char c[1] = {'A'};
for(i = 0; i < 16; i++)
{
fwrite(c, sizeof(char), 1, fp);
c[0]++;
}
int ip[1] = {1};
fwrite(ip, sizeof(int), 1, fp);
fwrite(ip, sizeof(int), 1, fp);
fwrite(ip, sizeof(int), 1, fp);
fclose(fp);
Если файл 'sample.bin' просматривается с помощью программы дампа, такой как 'od', он дает содержимое следующим образом.
od -t x1 -c sample.bin
0000000 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50
A B C D E F G H I J K L M N O P
0000020 01 00 00 00 01 00 00 00 01 00 00 00
001 \0 \0 \0 001 \0 \0 \0 001 \0 \0 \0
0000034
Этот код
#include <stdio.h>
#define SECTORSIZE 512 // bytes per sector
int main(int argc, char *argv[])
{
FILE *fp; // filepointer
size_t rdcnt; // num. read bytes
unsigned char buffer[SECTORSIZE];
if(argc < 2)
{
fprintf(stderr, "usage:\n\t%s device\n", argv[0]);
return 1;
}
fp = fopen(argv[1], "rb");
if(fp == NULL)
{
fprintf(stderr, "unable to open %s\n",argv[1]);
return 1;
}
rdcnt = fread(buffer, 1, SECTORSIZE, fp);
if(rdcnt != SECTORSIZE)
{
fprintf(stderr, "reading %s failed\n", argv[1]);
fclose(fp);
return 1;
}
fwrite(buffer, 1, SECTORSIZE, stdout);
fclose(fp);
return 0;
}
любезно взято отсюда https://redeaglesblog.wordpress.com/2011/04/05/sektoren-eines-datentragers-lesen/
читает загрузочный сектор с любого диска
Вставляемый, как и в ваш предпочтительный IDE или редактор C (ANSI), он компилируется и работает либо в Windows (mingw transmission \.\PhysicalDriveX), либо в linux (gcc pass/dev/sdX)
Но он работает как шарм ТОЛЬКО в Linux, хотя он в любом случае вставляет/добавляет x0D, предшествующий любому x0A, презирая fp = fopen(argv[1], "rb");
Я скомпилировал его из кода:: blocks с mingw как readsect.exe
и запустил его, прочитав загрузочный сектор моего жесткого диска
c:\readsect.exe \\.\PhysicalDrive0 > read.bin
Файл read.bin имеет длину в 515 байт вместо 512.
С помощью редактора HEX, способного открывать физические диски, я сравнивал содержимое загрузочного сектора с read.bin.
Ну, каждый x0A в физическом загрузочном секторе (x0A найден 3 раза), в файле read.bin выгружается как x0D + X0A. Таким образом, у меня есть три x0D, еще три байта.
Google, это похоже на широко известную проблему.
Кто-нибудь из вас нашел исправление? Может быть, stdio.h нуждается в исправлении для среды Windows?
Спасибо