Converting massive binary input string into character string C - c

I'm not familiar with C at all so this might be a simple problem to solve. I'm trying to take an input char* array of binary character sequences, ex. "0100100001101001", and output its relative string ("Hi"). The problem I'm having is coming up with a way to split the input into seperate strings of length 8 and then convert them individually to ulimately get the full output string.
char* binaryToString(char* b){
char binary[8];
for(int i=0; i<8; ++i){
binary[i] = b[i];
}
printf("%s", binary);
}
I'm aware of how to convert 8-bit into its character, I just need a way to split the input string in a way that will allow me to convert massive inputs of 8-bit binary characters.
Any help is appreciated... thanks!

From what I can tell, your binaryToString() function does not do what you'd want it to. The print statement just prints the first eight characters from the address pointed to by char* b.
Instead, you can convert the string of 8 bits to an integer, utilizing a standard C function strtol(). There's no need to convert any further, because binary, hex, decimal, etc, are all just representations of the same data! So once the string is converted to a long, you can use that value to represent an ASCII character.
Updating the implementation (as below), you can then leverage it to print a whole sequence.
#include <stdio.h>
#include <string.h>
void binaryToString(char* input, char* output){
char binary[9] = {0}; // initialize string to 0's
// copy 8 bits from input string
for (int i = 0; i < 8; i ++){
binary[i] = input[i];
}
*output = strtol(binary,NULL,2); // convert the byte to a long, using base 2
}
int main()
{
char inputStr[] = "01100001011100110110010001100110"; // "asdf" in ascii
char outputStr[20] = {0}; // initialize string to 0's
size_t iterations = strlen(inputStr) / 8; // get the # of bytes
// convert each byte into an ascii value
for (int i = 0; i < iterations; i++){
binaryToString(&inputStr[i*8], &outputStr[i]);
}
printf("%s", outputStr); // print the resulting string
return 0;
}
I compiled this and it seems to work fine. Of course, this can be done cleaner and safer, but this should help you get started.

I just need a way to split the input string in a way that will allow me to convert massive inputs of 8-bit binary characters.
You can use strncpy() to copy the sequence of '0' and '1' in a chunk of 8 characters at a time from the input string, something like this:
//get the size of input string
size_t len = strlen(b);
//Your input array of '0' and '1' and every sequence of 8 bytes represents a character
unsigned int num_chars = len/8;
//Take a temporary pointer and point it to input string
const char *tmp = b;
//Now copy the 8 chars from input string to buffer "binary"
for(int i=0; i<num_chars; ++i){
strncpy(binary, tmp+(i*8), 8);
//do your stuff with the 8 chars copied from input string to "binary" buffer
}

Maybe this can help. I didnt compile it but there is the idea. You can loop every 8 bit separately with while loop. And assign 8 bit to binary array with for loop. After that send this binary array to convert8BitToChar function to get letter equivalent of 8 bit. Then append the letter to result array. I'm not writing c for 3 year if there is mistakes sorry about that. Here pseudo code.
char* binaryToString(char* b){
char* result = malloc(sizeof(256*char));
char binary[8];
int nextLetter = 0;
while (b[nextLetter*8] != NULL) { // loop every 8 bit
for(int i=0; i<8; ++i){
binary[i] = b[nextLetter*8+i];
}
result[nextLetter] = 8bitToChar(binary));// convert 8bitToChar and append yo result
nextLetter++;
}
result[nextLetter] = '\0';
return result;
}

Related

Parsing a char[] of integers into ints i

I used fgets() to read input of a file into a
char buf[10];
the input of the file is
10,10,4,10
I want to iterate through the line and store each number in the char array as its own individual integer value but I am a little lost on how to do that. If someone could point me in the right direction I'd really appreciate it, thanks!
There are different approaches to do this. If you are learning C, I would recommend writing your own by-hand solution and after understanding how it works, use some standard library functions like strtok as #Jeff Holt said.
The easiest approach is to create a variable which will be the current number which we are reading and iterate over the buf array and at each step check if the current character is a number or not.
See this question about converting characters to integers.
So the result will be something like that:
const int size = 10;
char buf[size];
// fill buf, but be sure that input is less than 10 characters
//create array for result
char result[size];
int result_size = 0;
//can also be char, but if input numbers are big enough, it might overflow
int current_value = 0;
for (int i = 0; i < size; i++) {
if (buf[i] >= '0' && buf[i] <= '9') {
//convert to int and add to current_value
} else {
//store parsed integer
result[current_size] = current_value;
current_size++;
current_value = 0;
}
}

Add up digit from char array in c language

I am new to C programming and trying to make a program to add up the digits from the input like this:
input = 12345 <= 5 digit
output = 15 <= add up digit
I try to convert the char index to int but it dosent seems to work! Can anyone help?
Here's my code:
#include <stdio.h>
#include <string.h>
int main(){
char nilai[5];
int j,length,nilai_asli=0,i;
printf("nilai: ");
scanf("%s",&nilai);
length = strlen(nilai);
for(i=0; i<length; i++){
int nilai1 = nilai[i];
printf("%d",nilai1);
}
}
Output:
nilai: 12345
4950515253
You have two problems with the code you show.
First lets talk about the problem you ask about... You display the encoded character value. All characters in C are encoded in one way or another. The most common encoding scheme is called ASCII where the digits are encoded with '0' starting at 48 up to '9' at 57.
Using this knowledge it should be quite easy to figure out a way to convert a digit character to the integer value of the digit: Subtract the character '0'. As in
int nilai1 = nilai[i] - '0'; // "Convert" digit character to its integer value
Now for the second problem: Strings in C are really called null-terminated byte strings. That null-terminated bit is quite important, and all strings functions (like strlen) will look for that to know when the string ends.
When you input five character for the scanf call, the scanf function will write the null-terminator on the sixth position in the five-element array. That is out of bounds and leads to undefined behavior.
You can solve this by either making the array longer, or by telling scanf not to write more characters into the array than it can actually fit:
scanf("%4s", nilai); // Read at most four characters
// which will fit with the terminator in a five-element array
First of all, your buffer isn't big enough. String input is null-terminated, so if you want to read in your output 12345 of 5 numbers, you need a buffer of at least 6 chars:
char nilai[6];
And if your input is bigger than 5 chars, then your buffer has to be bigger, too.
But the problem with adding up the digits is that you're not actually adding up anything. You're just assigning to int nilai1 over and over and discarding the result. Instead, put int nilai1 before the loop and increase it in the loop. Also, to convert from a char to the int it represents, subtract '0'. All in all this part should look like this:
int nilai1 = 0;
for (i = 0; i < length; i++) {
nilai1 += nilai[i] - '0';
}
printf("%d\n", nilai1);
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
This character array
char nilai[5];
can not contain a string with 5 digits. Declare the array with at least one more character to store the terminating zero of a string.
char nilai[6];
In the call of scanf
scanf("%s",&nilai);
remove the operator & before the name nilai. And such a call is unsafe. You could use for example the standard function fgets.
This call
length = strlen(nilai);
is redundant and moreover the variable length should be declared having the type size_t.
This loop
for(i=0; i<length; i++){
int nilai1 = nilai[i];
printf("%d",nilai1);
}
entirely does not make sense.
The program can look the following way
#include <stdio.h>
#include <ctype.h>
int main(void)
{
enum { N = 6 };
char nilai[N];
printf( "nilai: ");
fgets( nilai, sizeof( nilai ), stdin );
int nilai1 = 0;
for ( const char *p = nilai; *p != '\0'; ++p )
{
if ( isdigit( ( unsigned char ) *p ) ) nilai1 += *p - '0';
}
printf( "%d\n", nilai1 );
return 0;
}
Its output might look like
nilai: 12345
15

How to convert a character from a file into an ascii integer into an array?

I am attempting to put a list of characters AND integers into an array of just integers. The file.txt looks like:
a 5 4 10
4 10 a 4
In the array I want the values to come out as {97,5,4,10,4,10,97,4}
This is part of my code:
int * array = malloc(100 * sizeof(int));
FILE* file;
int i=0;
int integer = 1;
file=fopen(filename,"r");
while (fscanf(file,"%d",&integer) > 0)
{
array[i] = integer;
i++;
}
Your problem is that, at first read, your while condition will exit because first element in the file is a char and fscanf won't interpret it as an integer, returning 0. I would suggest, if you are sure that your separator is a space, reading a string (it will automatically stop at space) and convert read value to int with strtol.
Something like:
int * array = malloc(100 * sizeof(int));
FILE* file;
int i=0;
char tmp[2], *pEnd;
file=fopen("./test.txt","r");
while (fscanf(file,"%s",tmp) > 0)
{
if( !(array[i] = strtol(tmp, &pEnd,10)))
array[i] = tmp[0];
i++;
}
Note that I assumed that you'll have no integer bigger than one digit (tmp array size) and that I check strtol response for detecting non integer chars.
It seems to me that what you want to do is use fscanf("%s", some_string) since numerics can be received as strings but strings cannot be received as numerics. Then with each input, you need to decide if the string is actually numeric or not, and then derive the value you want to place into the array accordingly.

sscanf doesn't move, scanning same integer everytime

I have a string that has ints and I'm trying to get all the ints into another array. When sscanf fails to find an int I want the loop to stop. So, I did the following:
int i;
int getout = 0;
for (i = 0; i < bsize && !getout; i++) {
if (!sscanf(startbuffer, "%d", &startarray[i])) {
getout = 1;
}
}
//startbuffer is a string, startarray is an int array.
This results in having all the elements of startarray to be the first char in startbuffer.
sscanf works fine but it doesn't move onto the next int it just stays at the first position.
Any idea what's wrong? Thanks.
The same string pointer is passed each time you call sscanf. If it were to "move" the input, it would have to move all the bytes of the string each time which would be slow for long strings. Furthermore, it would be moving the bytes that weren't scanned.
Instead, you need to implement this yourself by querying it for the number of bytes consumed and the number of values read. Use that information to adjust the pointers yourself.
int nums_now, bytes_now;
int bytes_consumed = 0, nums_read = 0;
while ( ( nums_now =
sscanf( string + bytes_consumed, "%d%n", arr + nums_read, & bytes_now )
) > 0 ) {
bytes_consumed += bytes_now;
nums_read += nums_now;
}
Convert the string to a stream, then you can use fscanf to get the integers.
Try this.
http://www.gnu.org/software/libc/manual/html_node/String-Streams.html
You are correct: sscanf indeed does not "move", because there is nothing to move. If you need to scan a bunch of ints, you can use strtol - it tells you how much it read, so you can feed the next pointer back to the function on the next iteration.
char str[] = "10 21 32 43 54";
char *p = str;
int i;
for (i = 0 ; i != 5 ; i++) {
int n = strtol(p, &p, 10);
printf("%d\n", n);
}
This is the correct behavior of sscanf. sscanf operates on a const char*, not an input stream from a file, so it will not store any information about what it has consumed.
As for the solution, you can use %n in the format string to obtain the number of characters that it has consumed so far (this is defined in C89 standard).
e.g. sscanf("This is a string", "%10s%10s%n", tok1, tok2, &numChar); numChar will contain the number of characters consumed so far. You can use this as an offset to continue scanning the string.
If the string only contains integers that doesn't exceed the maximum value of long type (or long long type), use strtol or strtoll. Beware that long type can be 32-bit or 64-bit, depending on the system.

Conversion from Byte to ASCII in C

Can anyone suggest means of converting a byte array to ASCII in C? Or converting byte array to hex and then to ASCII?
[04/02][Edited]: To rephrase it, I wish to convert bytes to hex and store the converted hex values in a data structure. How should go about it?
Regards,
darkie
Well, if you interpret an integer as a char in C, you'll get that ASCII character, as long as it's in range.
int i = 97;
char c = i;
printf("The character of %d is %c\n", i, c);
Prints:
The character of 97 is a
Note that no error checking is done - I assume 0 <= i < 128 (ASCII range).
Otherwise, an array of byte values can be directly interpreted as an ASCII string:
char bytes[] = {97, 98, 99, 100, 101, 0};
printf("The string: %s\n", bytes);
Prints:
The string: abcde
Note the last byte: 0, it's required to terminate the string properly. You can use bytes as any other C string, copy from it, append it to other strings, traverse it, print it, etc.
First of all you should take some more care on the formulation of your questions. It is hard to say what you really want to hear. I think you have some binary blob and want it in a human readable form, e.g. to dump it on the screen for debugging. (I know I'm probably misinterpreting you here).
You can use snprintf(buf, sizeof(buf), "%.2x", byte_array[i]) for example to convert a single byte in to the hexadecimal ASCII representation. Here is a function to dump a whole memory region on the screen:
void
hexdump(const void *data, int size)
{
const unsigned char *byte = data;
while (size > 0)
{
size--;
printf("%.2x ", *byte);
byte++;
}
}
Char.s and Int.s are stored in binary in C. And can generally be used in place of each other when working in the ASCII range.
int i = 0x61;
char x = i;
fprintf( stdout, "%c", x );
that should print 'a' to the screen.

Resources