Socket recv in c++ - c++

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.

Related

C++ string push_back function not working

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.

Rotate a bool array in C++

EDIT
I found the memcpy definition has told us about its undefined behavior when target and src has overlap:
The memcpy() function copies n bytes from memory area src to memory area dst. If dst and src overlap, behavior is undefined.Applications in which dst and src might overlap should use memmove(3) instead.
Original Question
I have a simple program that looks like this:
static void RotateLeft(bool *In, int len, int loop) {
for(int i = 0;i< 28;i++) {
LOGI("%d -> %d", i, In[i]);
}
bool Tmp[256] = {0};
memcpy(Tmp, In, loop);
memcpy(In, In + loop, len - loop);
LOGI("len = %d, loop = %d", len, loop); // <--- always 28 and 1
for(int i = 0;i< 28;i++) {
LOGI("%d -> %d", i, In[i]); <----- broken
}
memcpy(In + len - loop, Tmp, loop);
}
RotateLeft(`bool array`, 28, 1)
It is weird that this program doesn't work right on the arm64-v8a platform (but works well on other platforms):
The input array is something like this:
0 0 0 1 1 1 1 0 1 0 0 1 0 1 ...
The rotated array should be:
0 0 1 1 1 1 0 1 0 0 1 0 1 0...
But it actually outputs:
0 0 1 1 1 1 0 1 0 0 1 1 0 0 ...
UPDATE
Here's how this program allocate array:
bool K[64], *KL=&K[0], *KR=&K[28];
// do something fill `K`
RotateLeft(KR, 28, 1);
The underlying assumption for this code is that sizeof(bool) is 1. Unfortunately, this is not guaranteed by the C++ standard as explained in this answer. So your code is completely compiler dependent.
Therefore use std::copy() whenever you can instead of memcpy(). Or use std::rotate() as suggested by NathanOlivier in the comments.
By the way, it's unrelated, but you'd better make sure that loop>=0 && loop<256 && len>=loop if you want to avoid undefined behavior.

Reading single lines from file into vector

I have an input file of the following format:
# 1 2 3 4 5 6 7
0 0 0 1
1 0 0 1
2 0 0 1
3 0 0 1
5 0 0 1
6 0 0 1
# 0 0 2 2 4 4 5
0 0 0 1
0 1 0 1
0 2 0 1
0 3 0 1
# 9 10 11 12 13 14 15 16 17 18
0 0 0 1
0 0 1 1
0 0 2 1
0 0 3 1
Each line preceded by a # must be read into its own vector. The entries in between these vectors represent matrices that also must be read into their own matrix.
So from the input file above, what I want to end up having is the following:
knot1 = {1 2 3 4 5 6 7}
cp1= { {0,0,0,1} {1,0,0,1} {2,0,0,1} {3,0,0,1} {5,0,0,1} {6,0,0,1} }
knot2 = {0 0 2 2 4 4 5}
cp2= {{...} {...} {...} {...} }
knot3 = {9 10 11 12 13 14 15 16 17 18}
cp3= {{...} {...} {...} {...} }
Note, each vector is not necessarily the same size! Same goes for the matrices. Also, the number of #vectors and matrices can vary as well.
Here is what I have so far:
ifstream file;
file.open(filename.c_str());
if(file.fail()){
cout << "Cannot open " << filename << endl;
}
int curr_line = 0;
vector<int> knot_locations; //stores the locations of the #vectors
while(!file.eof()){ //loops over input file checking to see where the #vectors are
curr_line++;
string line;
getline(file,line);
if(line[0]=='#'){
knot_locations.push_back(curr_line);
}
}
for(int i=0; i < knot_locations.size(); i++){
file.seekg(std::ios::beg);
for(int i=0; i < knot_locations[i] - 1; ++i){ // this loop skips to the line that contains the #vectors.
file.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
}
so now that I am at the line
containing the vector, how can I read
in JUST that SINGLE line into a vector?!
I'm not sure how to turn a string into
a vector of floats. Also, since I know all the
locations of the vectors, I can read everything
else between into the matrices. But again, same
problem. I am not sure how to go about actually
reading these into a numeric array/vector given a line (string)
file.close();
Probably better ways of doing this. Any ideas on how to go about this problem? The key is to be able to read all the vectors marked with a # into their own vector. There can be anywhere between 1-3 of these vectors. And in between each of these vectors is a matrix of unknown rows/columns that also need to be read into their own matrix. What I have above just locates the # marked vectors. Need help on how to read a string line into a numeric array OR a recommendation on a different way to go about this.
Thank you.

String and ascii values

In this piece of code if i run a for loop to know elements stored inside the array c I get output as 1 1 1 0 0 0 0 1 0 0.
The input is abc. Why it does it give 1 1 1 instead of 0 1 2 0 0 0 0 0 0?
int c[26]={};
cin >> s;
len = s.length();
for(int i = 0 ; i < len ; i++ ){
c[s[i] - 'a'] ++ ;
}
Your c array is a histogram of the characters read. Your output is saying you read 1 'a', 1 'b' and 1 'c'. Try c[s[i] - 'a'] = s[i] - 'a';
Your code is basically counting the number of letters in a string. The count is stored in the array c where the index represents the letter index in the alphabet. So a is 0, b is 1, c is 2 and so on.
So for abc the correct input is indeed 1 1 1, due to the fact that there's 1 a, 1 b and 1 c. Your 0 1 2 would represent a string with 1 b and 2 cs.
s[i] - 'a'
That is returning 0, 1 and 2. But
c[s[i] - 'a'] ++ ;
Is always increasing 1 each occurrence of C[] which at the beginning was initializing with all zeros. For that reason you get all 1s in your output.
Try
c[s[i] - 'a'] = s[i] - 'a'

c/c++ stock bitmap using hexadecimal letters and convert back

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);