SQLite dropping zeros - sqlite

I'm using google wrapper (sqlite3pp) to insert a char array that contain some zeros. The problem that is the SQLite is dropping the zero and the next elements after it.
char array[11] = {1,2,3,4,5,0,3,4,0,6,7};
sqlite3pp::command cmd(db, "INSERT INTO messages (id, payload) VALUES (?, ?)");
cmd.bind(1,index);
cmd.bind(2,&array[0],sizeof(array));
This code only insert: 1 2 3 4 5
The payload type is varchar.
Any idea?

sqlite3pp defines, among others, these two overloads for the bind() function:
int bind(int idx, char const* value, bool fstatic = true);
int bind(int idx, void const* value, int n, bool fstatic = true);
You want to use the second one with explicit length, but the first one is selected, while sizeof(array), evaluated to be 11, is truncated to bool value true and passed as fstatic instead of size. The wrapper then thinks the value is a plain NUL-terminated string and thus stores just the part till the first zero.
You can help the compiler to select the right version e.g. by providing the implicit parameter like so:
cmd.bind(2, &array[0], sizeof(array), true);
(Or false when the array will be deallocated before the query is done executing.)
Additionally, there can be problems with reading the rows as well - e.g. the default sqlite3pp getter for std::string won't work with binary zeroes and the content needs to be retrieved explicitly like this:
payload.assign(static_cast<const char*>(i->get<const void*>(2)), i->column_bytes(2));

Related

Need to understand how char * strcpy (char *cad1, const char *cad2) works in C

Can't get how a method with this head: char * strcpy (char *cad1, const char *cad2), works in C in this sample:
'char * strcpy (char *cad1, const char *cad2){
char *aux = cad1;
for( ; *cad1++ = *cad2++; );
return cad1;
}'
Starting from the method signature or prototype, that tells a lot about the how it works: we have two parameters together with their respective types and a return type. All parameters in this case are pointers to char, more known as char pointers. Those char pointers are what is used in "C" as strings of characters. One parameter is a const, because that value must not be changed in the function, it MUST keep, the original value.
Strings in "C" have some peculiarities, once the pointer is created to a string it always points to the first characters in the string or index 0, the same as char *v = var[0], and can be incremented passing to the next char in the string such as v++. Other peculiarity in "C" is that all strings represented by char arrays end with a 0 character (ASCII null = 0).
The strcpy version account on that concepts and makes a for loop to copy each element in the char *cad2 to *cad1, that variables MUST be allocated statically or dynamically (malloc) before calling the function, and the return of the function in the code above is a pointer to the original variable (in that case *cad1, normally they return the copied one). In your function it was changed, I mean it is returning the original instead of the copied what looks wrong since you catch in the aux the pointer to the first element of the copied variable and you did not use it.
One good point to observe is the for loop:
for( ; *cad1++ = *cad2++; );
How it works is tricky, the first interesting point is that the for loop has tree parameters, and in "C" all are optional. The first is to initialize, the second is a boolean condition to continuing iterating, and the last one is to increment or decrement.
Next, tricky is is *cad1++ = *cad2++ a boolean expression? The answer is yes, it is. Since in "C" the value 0 (zero) is false, and anything else is true. Remember that I have said strings in "C" finishes always with a 0 (zero), so when evaluating and assigning to the copy the value of a pointer (using *cad1 will return the value pointed by a pointer variable, the star in the begin makes that magic) and reaches the end of the string that will return false and finish the iteration loop.
One point is interesting here, first the evaluation has less priority than the assignment in this case, what makes first the value being copied to the copy variable, then evaluating the boolean expression.
"C" is like this you writes a small code that have large meaning behind it. I hope you have understood the explanation. For further information have a look in "C" pointers at : https://www.tutorialspoint.com/cprogramming/c_pointers.htm.
char * strcpy (char *cad1, const char *cad2){
for( ; *cad1++ = *cad2++;);
return cad1;
}
the way this works, at the calling side, it can be used in two ways, but always requires a buffer to write to so the use is simmilar.
char arr[255];
memset(arr,0,sizeof(char) * 255); // clear the garbage initialized array;
strcpy(arr, "this is the text to copy that is 254 characters long or shorter.");
puts(arr);
or
char arr[255];
memset(arr,0,sizeof(char) * 255);
puts(strcpy(arr,"hello C!"));
sense the function returns the pointer to the buffer this works as well.

How can a 1 byte int conversion of a QByteArray fail?

So here is the thing, I'm receiving 1 byte from Bluetooth transmission. When using QDebug I get this message:
The array with error has "\x06"
The line that fails is this:
bool ok = true;
int v = value.toInt(&ok,0);
Because ok has false. But I'm trying to wrap my head around the fact that, How can the conversion fail in the first place if the data represented in that byte (as a sequence of zeros and ones) will always have a valid integer representation. (one byte can always be represented as a int between -127 and 128). So I'm left with the question, how can the conversion fail?
Reading the documentation does not provide many clues as it does not say how the byte array will be interpreted.
QByteArray::toInt converts a string representation in the default C locale to an integer. That means to successfully convert the value in your example, your byte array must contain the string "0x06", which consists of 4 bytes.
To convert a single byte to an int, just extract it:
int i = value[0];
Type promotion will widen the char to an int

ARDUINO: I can't manage to use a variable as index for my array

int sum = 3;
int i = 0;
myCode[] = {};
void loop () {
myCode[i] = sum;
}
In this example the variable 'i' gets the value of '3' instead of assigning the value of '3' to the array myCode[] with the index '0' (i).
I honestly don't know why it does this. This is only a small part of the program. I don't include the full program because that would only be confusing for you guys and this is the only part of the program that is not working.
How would I use the value of i to assign a value to the array with i as index??
It looks like you see undefined behavior, because myCode array does not have enough space. Since you see myCode[0] modifying the value of i instead of myCode, the size of myCode in your compiled program is zero, and its address is the same as i's address.
Fixing this problem requires allocating myCode at the max size that you expect it to have:
int myCode[20] = {0};
Now the code is going to work correctly for indexes between 0 and 19, inclusive.

How can i split a wchar_t / TCHAR / WCHAR / LPTSTR into a QStringList?

While working with the Win32API, the function i must use returns its results by writing them to buffer of type LPTSTR as well as the individual number of characters that were written.enter code here
As this buffer is a string, and the function can return multiple values, the actual result data look something like this:
Value1\0Value2\0Value3\0\0
What is the best way to get this into a QStringList?
LPTSTR = Long Pointer to TCHAR. On modern systems (those with unicode support) this is synonymous with a WCHAR array.
Since your output buffer will contain characters where each is two bytes it is thus compatible with UTF16.
QString has a fromUtf16 static method which requires a simple cast to satisfy the compiler.
In this case, we MUST also specify the total length of the entire string. Failure to do this results in QString only reading the input data up until the first null character, ignoring any other result data.
Once we actually have a QString to work with, splitting it is simple. Call QString's split() method specifying a null character wrapped in a QChar.
Optionally, and required in my case, specifying SplitBehavior as SkipEmptyParts ensures that no empty strings (the result of parsing the null character) end up in my desired result (the QStringList of values).
Example:
// The data returned by the API call.
WCHAR *rawResultData = L"Value1\0Value2\0Value3\0";
// The number of individual characters returned.
quint64 numberOfWrittenCharacters = 22;
// Create a QString from the returned data specifying
// the size.
QString rString =
QString::fromUtf16((const ushort *)rawResultData, numberOfWrittenCharacters);
// Finally, split the string into a QStringList
// ignoring empty results.
QStringList results =
rString.split(QChar(L'\0'), QString::SkipEmptyParts);

swapping address values of pointers

Below is code and I want to ask, why I am not getting swapped number as a result, because instead of swapping numbers I tried to swap their addresses.
int *swap(int *ptr1,int *ptr2){
int *temp;
temp = ptr1;
ptr1= ptr2;
ptr2=temp;
return ptr1,ptr2;
}
int main(){
int num1=2,num2=4,*ptr1=&num1,*ptr2=&num2;
swap(ptr1,ptr2);
printf("\nafter swaping the first number is : %d\t and the second number is : %d\n",*ptr1,*ptr2);
}
I can see two problems in your code.
First, within the swap function, ptr1 and ptr2 are local copies of the pointers in main with the same name. Changing them in swap only changes those copies, not the originals.
Second, the return statement doesn't do anything useful. The function swap is declared as returning a single int *. The return statement actually only returns ptr2 - for why that is, look up the "comma operator" in C. But you ignore the return value in main anyway, so it makes no odds.

Resources