Подтвердить что ты не робот

Странный 0x0D добавляется в мой двоичный файл

У меня есть эта странная проблема:

Я пишу 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

Есть ли у кого-нибудь идея, почему это может случиться?

4b9b3361

Ответ 1

0A - символ подачи строки, а 0D - возврат каретки. Обычно они связаны с текстовым режимом.

Вы открыли файл в двоичном режиме? (например, fopen("foo.txt", "wb"))

Ответ 2

Когда вы открываете файл, откройте для записи как двоичный "wb":

fopen(filename, "wb");

Когда вы открываете в текстовом режиме, происходит перевод Line Feeds (0A) и возврат каретки (0D).

Ответ 3

fopen файл в двоичном режиме с "wb".

fopen(filename, "wb");

в противном случае код в библиотеке будет выполнять автоматический перевод конца строки (на окнах вы на Windows, не правда ли?, что означает перевод '\n' в '\r' '\n').

Ответ 4

MS-DOS (и так сегодня с Windows) при записи файла в текстовом режиме добавляет 0x0D перед каждым 0x0A. Другими словами, он обрабатывает произвольные потоки данных по мере их поступления и из хранилища и беспорядок с их данными - совершенно безумно.

Откройте файл в двоичном режиме для безумной обработки.

Ответ 5

Я считаю, что ваша переменная 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

Ответ 6

Этот код

    #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?

Спасибо