I have a bitmap stocked as a unsigned char array, containing only 1 and 0; like this:
0 0 0 0 1 1 1 1
0 0 1 1 0 0 1 1
I wish to stock this in a compact way, so I wrote a function to convert this into hexadecimals. I'll stock this like:
0f33
My question now: with which function can I convert these characters back into my bitmap? when I have a pointer to the character "f", how can I convert that into the integer value 15? (I know a switch case would do the trick, but probably there is a better way?)
Try this for C++:
int number;
std::stringsteam ss;
ss << std::hex << *characterPointer;
ss >> number;
For C:
char hexstr[2] = {*characterPointer, '\0'};
int number = (int)strtol(hexstr, NULL, 16);
Related
I am trying to generate strings with {0, 1, 2} using an integer queue to store numbers until I am ready to check if they are binary numbers. I am starting with single digits and then appending them to get longer and longer number strings. So the order I am trying to get is 0, 1, 2, 00, 01, 02, 10, 11, 12, 20, 21, 22, 000, 001, 002, 010, 011, 012 e.t.c. The problem I am having though is that when I dequeue an integer from my queue, turn it into a string and try to append it with {0, 1, 2} using s.push_back(app), nothing is appended. Below is my code and output.
int main()
{
string s; //holds strings of numbers that come from the int queue
bool isBin; //holds the boolean value returned from recognizer
int count=0; //while loop counter to not go over 20 iterations
Queue myQ; //queue created to hold all values generated
int numHolder; //holds values dequeued from int queue to be turned into string
myQ.enQueue(0);//queue 3 initial values to work with
myQ.enQueue(1);
myQ.enQueue(2);
while(count<=20)//while loop doesnt go over 20 iterations of binary numbers
{
numHolder=myQ.deQueue();//holds int values dequeued from queue
s=to_string(numHolder);//converts the int from queue to a string
/* isBin=recognizer(s);//send the string to the recognizer
if(isBin==true)
{
cout<<s<<endl;//prints string if it is binary number
count++;//increment counter because string was binary
}*/
for(int i=0; i<3; i++)//this loop adds 0 then 1 then 2 to the end of each dequeued string
{
char app = i;
s.push_back(app);//this is where string is appended with 0 1 or 2
cout<<s<<endl;
int newNum=stoi(s);//new appended string is turned into integer
myQ.enQueue(newNum);//new integer is put into queue
s.pop_back();//pops back the string so other numbers can be created with the original dequeued string
}
count++;
}
// }// end of while
}// end of main
output:
0
0
0
1
1
1
2
2
2
0
0
0
0
0
0
0
0
0
1
1
1
1
1
1
1
1
1
2
2
2
2
2
2
2
2
2
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
I can tell by the output it has the right order for the first characters but nothing is being appended to them because the string push_back function is not working. Please help!
char app=i stores the characters whose binary value is 0 1 and 2, not the characters '0', '1' and '2'.
Try char app = '0'+i;
In C/C++ char is both a number type and the traditional way to store a single character. The conversion from int just treats char like a number type.
I'm trying to implement an oscilloscope for a digital input and send it over a serial port for debugging. I have the scope software sending Matlab a string like "000000111111111000000001111111000000". I'd like to plot this. Is there any way for me to split this string into a vector. It doesn't seem Matlab allows you to use strsplit() without a delimiter. I'd rather not bog up the communications with a delimiter between each byte.
With MATLAB's weak typing, this is actually quite easy:
>> str = '000000111111111000000001111111000000'
str = 000000111111111000000001111111000000
>> class(str)
ans = char
>> vec = str - '0'
vec =
Columns 1 through 22:
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0
Columns 23 through 36:
0 1 1 1 1 1 1 1 0 0 0 0 0 0
>> class(vec)
ans = double
This subtracts the ordinal value of the character '0' from each character in the string, leaving the numerical values 0 or 1.
You can use sscanf with a single value width:
a = '000000111111111000000001111111000000'
b = sscanf(a, '%1d');
Which returns:
>> b.'
ans =
Columns 1 through 18
0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 0 0 0
Columns 19 through 36
0 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 0 0
A quick and fast solution is:
data = '000001111111110000000000111111111110000000';
vec = str2double(cellstr(data.').');
It will produce a column vector of numeric values. If you want a row vector as output, just use a single transpose:
vec = str2double(cellstr(data.'));
I'm surprised how difficult this is to do. But here's what I came up with:
str = '000001111111110000000000111111111110000000'; %test string
y = cellfun(#(x) str2num(x), regexp(str,'\d','match'));
plot(y);
regexp() seems to be the only way to go. By default, it return indexes of matches so you need to specify 'match'. Then you end up with a cell array of strings. The only good way to convert this into a numerical array is one item at a time with str2num().
I hope this helps someone else out who is assuming there is a straight forward function as I assumed. And if anyone knows a way to do this without converting my "01...01....01....01....00....00....00....00" stream of bytes into the ascii representations of the binary numbers: "49.....49.....49....49....48....48....48....48", I'd love to hear it.
I created a matrix class which contains an vector of vectors of a point object (another class i made). Every point in the matrix is walkable or not walkable (the matrix is actually a maze). 1 is walkable, 0 is not.
I want to get the matrix in this form:
4 4 //size of the maze (matrix)
1 0 1 0 (enter)
1 1 0 0 (enter)
0 1 1 0 (enter)
1 0 1 1 (enter)
I tried to get row by row, and then seperate the points (1s and 0s) by stream string. This is my code:
istream & operator >> (istream& input, maze inMaze) {
string rowStream;
string tmpWord;
int num, colCounter; //num = 1 or 0, colCounter = col index
for (int rowIndex = 0; rowIndex < inMaze.rowsSize; rowIndex++){ //over the rows
int colIndex = 0;
bool isWalkable;
input >> rowStream; //input to string
stringstream seperateWord(rowStream); //string to stream string
while (seperateWord >> tmpWord) { //sstring seperate space bars in string, reprasant a row
if (tmpWord == "0") isWalkable = false; //in maze matrix, zero means not a path
else if (tmpWord == "1") isWalkable = true; //else 1 = a path
else throw "invalid input"; //wrong input (num in matrix not 0 nor 1)
inMaze.getMaze[rowIndex][colIndex].setPoint(rowIndex, colIndex, isWalkable); //set point in maze
colIndex++; //next col
} //done filling a row, to next row
}
}
It didnt work. It always ended getting the input after the first row, and filled everything with 1s.
What did I do wrong?
Thank you for your help! and sorry for my poor English.. :-)
The problem in line input >> rowStream; replace it with getline(input,line); and line is string type.
the operator >> of file take one argument ended with white space!
like: 00 1 0 11, first argument is 00, second is 1...
and in your case using stringstream which mean you must take whole line
like: 0 1 0 1 0 1, take it using getline, then use stringstream to get right input. 0 then 1 ...
My code is as below
char *inBuffer = new char[5];
int recvReturn = recv(Socket, inBuffer, sizeof(inBuffer) - 1, 0);
if (recvReturn <= 0)
{
m_manager->log("Socket receive error",HIGH_IMPORTANCE);
}
else
{
std::stringstream ss2;
ss2<<std::hex;
for(int i(0);i<5;++i)
ss2<<(int)inBuffer[i] << ' ';
m_manager->log(ss2.str(),HIGH_IMPORTANCE);
}
The result in my log is
1 1 6 0 0
The values on 1 1 6 are correct but 0 0 is wrong. Instead of 0 0 I expect 8 9. Is there something wrong in the code?
I can see 2 problems in your code.
you print 5 characters without ensuring you recieved at least 5. You should display recvBuffer and/or limit the number of chars written to that.
if you received bytes with value 1, 6, 8, 9 they are not printable characters. The (ASCII) code of 0 is 0x30 or 48. So ss2.str could be weird as a printable string.
I'm writing a program that converts a binary string to decimal. I wanted to validate my output before I get really started on this method. I have the following code:
int get_val()
{
int sum =0;
for(int num_bits = size; num_bits>0; num_bits--)
{
printf("String sub %i is %i\n", num_bits, int(bin[num_bits]));
}
}
When I input a string of 16 zeros, I get the following output:
String sub 16 is 24
String sub 15 is 0
String sub 14 is 0
String sub 13 is 0
String sub 12 is 23
String sub 11 is 0
String sub 10 is 0
String sub 9 is 0
String sub 8 is 22
String sub 7 is 0
String sub 6 is 0
String sub 5 is 0
String sub 4 is 21
String sub 3 is 0
String sub 2 is 0
String sub 1 is 0
Why would I bet getting different values if I input all zeros?
EDIT: bin is "0000000000000000"
As long as the question isn't updated, perhaps this example code helps. It converts a binary string into an integer. I tried to keep as much of your code and variable names as possible.
#include <stdio.h>
#include <stdlib.h>
#include <string>
using namespace std;
int main() {
string bin = "000111010";
int size = bin.length();
int sum = 0;
for(int num_bits = 1; num_bits <= size; num_bits++) {
sum <<= 1;
sum += bin[num_bits - 1] - '0';
}
printf("Binary string %s converted to integer is: %i\n", bin.c_str(), sum);
}
As already said in the comments, the main trick here is to convert the ASCII characters '0' and '1' to the integers 0 and 1 which is done by subtracting the value of '0'. Also, I changed the traverse order of the string because this way, you can shift the integer after each bit and always set the value of the currently lowest bit.
Short answer, you wouldn't.
Long answer, there are a few issues with this. The first big issue is that if we assume bin is a standard array of characters of length "size", then your first print is invalid. The array index is off by 1. Consider the code example:
int size = 16;
char * bin = new char[size];
for(int i=0; i<size; i++)
{
bin[i] = 0;
}
for(int num_bits = size; num_bits>0; num_bits--)
{
printf("String sub %i is %i\n", num_bits, int(bin[num_bits]));
}
Which produces:
String sub 16 is -3
String sub 15 is 0
String sub 14 is 0
String sub 13 is 0
String sub 12 is 0
String sub 11 is 0
String sub 10 is 0
String sub 9 is 0
String sub 8 is 0
String sub 7 is 0
String sub 6 is 0
String sub 5 is 0
String sub 4 is 0
String sub 3 is 0
String sub 2 is 0
String sub 1 is 0
Judging by the actual output you got, I'm guessing you did something like:
int size=16;
int * ints = new int[size];
char * bin;
//Fill with numbers, not zeros, based on the evidence
for(int i=0; i<size; i++)
{
ints[i] = 20 + i;
}
//Copy over to character buffer
bin = (char*)(void*)&(ints[0]);
for(int num_bits = size; num_bits>0; num_bits--)
{
printf("String sub %i is %i\n", num_bits, int(bin[num_bits]));
}
That explains the output you saw perfectly. So, I'm thinking your input assumption, that bin points to an array of character zeros, is not true. There are a few really big problems with this, assuming you did something like that.
Your assumption that the memory is all zero is wrong, and you need to explain that or post the real code and we will
You can't just treat a memory buffer of integers as characters - a string is made up of one byte characters (typically), integers are 4 bytes, typically
Arrays in C++ start at 0, not 1
Casting a character to an integer [ int('0') ] does not intelligently convert - the integer that comes out of that is a decimal 48, not a decimal 0 (there is a function atoi that will do that, as well as other better ones, or the other suggestion to use subtraction)