записать двоичную строку как двоичный файл в файл - PullRequest
1 голос
/ 09 октября 2011

Я хочу записать строку, состоящую только из нулей и единиц, в выходной файл, где выходной файл буквально содержит только нули и единицы в порядке, заданном строкой.

В данный момент я пытаюсьзаписать символ в размер 1 бит

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main(int argc, char *argv[])
{   
FILE *out_file;

out_file = fopen("out", "wb");

char s[] = "01010101010101010101"; /*20 chars*/
int i;

for (i = 0; i < 20; i++) {
    fwrite(&s[i], 1, 1, out_file);
}

fclose(out_file);

return EXIT_SUCCESS;
}

Выходной файл в шестнадцатеричном редакторе

30 31 30 31 30 31 30 31 30 31 30 31 30 31 30 31 30 31 3031

Таким образом, выходной файл содержит значения ascii для нуля и единицы, а не фактические нули и единицы.

Спасибо

Ответы [ 4 ]

1 голос
/ 09 октября 2011

Используйте escape-последовательности в строковом литерале для обозначения байтов 0x00 и 0x01, а не символов 0 и 1:

char s[] = "\x00\x01";
0 голосов
/ 09 октября 2011

Хорошо, вот ваше решение (хотя оно не очень тщательно проверено):

template<typename TItem, typename TItem2>
void SetEnableFlags(TItem &BitFlags, const TItem2 &Flags)
{
    BitFlags = (BitFlags|Flags);
}

const unsigned char CharArrayToByte(const char Data[])
{
    if(Data == NULL){return 0;}
    if(strlen(Data) < 8){return 0;}
    unsigned char Byte = 0;
    SetEnableFlags(Byte,(Data[0]-'0')*128);
    SetEnableFlags(Byte,(Data[1]-'0')*64);
    SetEnableFlags(Byte,(Data[2]-'0')*32);
    SetEnableFlags(Byte,(Data[3]-'0')*16);
    SetEnableFlags(Byte,(Data[4]-'0')*8);
    SetEnableFlags(Byte,(Data[5]-'0')*4);
    SetEnableFlags(Byte,(Data[6]-'0')*2);
    SetEnableFlags(Byte,(Data[7]-'0')*1);
    return Byte;
}

const bool ConvertToBytes(char Bytes[], const char Binary[])
{
    if( (Binary == NULL) || (Bytes == NULL) ){return false;}

    //Checks it's a power of 8
    int Size = strlen(Binary);
    if(Size < 8){return false;}
    float SizeTest = ((float)Size/8.0);
    if( (SizeTest - (int)SizeTest ) != 0.0 ){return false;}

    unsigned int Power = 0;
    unsigned int Iter = 0;
    do
    {
        Power = 8*Iter;
        Bytes[Iter] = CharArrayToByte( (Binary+Power)  );
        Iter++;
    }while(Power < Size);
    return true;
}

int main()
{
    char Bytes[3]; //Allocate enough space for it
    char Binary[] = "000000010000001100001111"; //1, 3, 15
    if(!ConvertToBytes(Bytes,Binary)){return 1;}

    printf("%d %d %d!\n",Bytes[0],Bytes[1],Bytes[2]);

    return 0;
}

Вы можете также прочитать эту ветку здесь , чтобы упростить свою работу.

Код не оптимизирован. Вы можете использовать его для любых целей, даже коммерческих (если вы можете продать его). Строки станут нечитаемыми за пределы 8 бит, поэтому вы можете просто вызвать CharArrayToByte вручную (убедитесь, что длина массива char действительно равна 8 символам, иначе у вас возникнут проблемы). Если вы хотите преобразовать его обратно, вам нужно обратить процесс вспять.

Неясно, используете ли вы C или C ++ (с кодированием C), поэтому вам, вероятно, придется изменить его в соответствии с вашими потребностями.

0 голосов
/ 09 октября 2011

Если вы пытаетесь выразить строку «011000100110100101110100» в качестве трехбайтовых значений 98, 105, 116, вам сначала нужно преобразовать их из массива символов (или «строки», как она вызывается в C) вчисловые значения массива.

Примерно так может быть хорошим началом:

unsigned char *convert(char *input)
{
  int len = strlen(input);
  /* Can only correctly handle strings that have 'full' bytes */
  unsigned char *rv = malloc(len/8); 
  char *cp;
  unsigned char *dp = rv;;
  char dp_inc = 0;

  for (cp = input; *cp; cp++) {
    *dp = ((*dp) << 1) | (*cp == '1');
    if ((++dp_inc) >= 8) {
      dp_inc = 0;
      dp++;
    } 
  }

  return rv;
}

Эта процедура проходит по входной строке и преобразует ее в двоичные числа, которые она представляет.Вероятно, это может быть связано с некоторой аккуратностью, поскольку это не обязательно образец читаемого кода, и он, вероятно, должен возвращать количество выделенных байтов и принимать ограничитель диапазона вместо того, чтобы полагаться на strlen.

0 голосов
/ 09 октября 2011

используйте тип байта, а не char и удалите эту строку, конечно, она показывает 0x30 для 0, вы попросили написать «0», а не 0 .... Вы можете указать двоичный файл, используя b byte b1 = 10001110b; конечно, вы не можете сделать из него массив, если вам нужны более длинные числа, вам придется написать их по одному или написать метод \ функцию для разбора двоичных строк для вас, если вы не существуете в открытом коде уже.

...