I want to write a string consisting of only zeroes and ones to a output file where the output file literally only contains the zeroes and ones in the order given by the string.
At the moment I am trying to write the char to a size 1 bit
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int ma开发者_Go百科in(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;
}
The output file in a hex editor
30 31 30 31 30 31 30 31 30 31 30 31 30 31 30 31 30 31 30 31
Thus the output file contains the ascii values for zero and one, and not actual zeros and ones.
Thank you
Use escape sequences within the string literal to denote the bytes 0x00
and 0x01
, not the characters 0
and 1
:
char s[] = "\x00\x01";
use byte type and not char and remove those string, of course it shows 0x30 for 0, you asked it to write '0' not 0.... you can specify binary by using b byte b1 = 10001110b; of course you can't make an array out of it, if you want longer numbers u'll have to write them one by one or write a method\function to parse binary strings for ya, if one doesn't exist in open source already.
If you're trying to express the string "011000100110100101110100" as the three byte values 98, 105, 116 you will first need to convert them from an array of chars (or "string" as it's called in C) to an array numerical values.
Something like this may be a good start:
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;
}
This routine steps through the input string and converts it to the binary number(s) it represents. It could probably do with some tidying-up, since it's not necessarily a paragon of readable code and should probably return the number of bytes allocated and take a range limiter instead of relying on strlen.
Okay, here's your solution (it's not very thoroughly tested though):
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;
}
You may want to consider also reading this thread here to make your job easier.
The code isn't optimised. You can use it for whatever purpose, even commercial (if you're able to sell it). Strings will get unreadable beyond 8 bits, so you may just wish to call CharArrayToByte manually (ensure the char array length is indeed 8 characters or you will have issues). If you want to convert it back, it's a matter of reversing the process.
It wasn't clear whether you were using C or C++ (with C coding), so you'll likely have to modify it to suit your needs.
精彩评论