uint16_t array to string and back c++ - c++

I have a uint16_t array and I want to be able to convert it to a string and convert it back.
The goal is to save the array with this library and load it back into a variable.
What would be the best approach?
I tried to read the json key to the variable
uint16_t *program;
program = json["script"];
but it gives me this error:
no suitable conversion function from "nlohmann::basic_json<std::map, std::vector, std::string, bool, int64_t, uint64_t, double, std::allocator, nlohmann::adl_serializer, std::vector<uint8_t, std::allocator<uint8_t>>>" to "uint16_t *" exists
That's why I thought that maybe I should convert it to another datatype with available conversion first.
Solved:
I used vector<uint16_t> instead of an uint16_t array, which had available conversion in the library.

Related

sscanf_s: format string '%d' requires an argument of type 'int *', but variadic argument 4 has type 'WORD *'

SYSTEMTIME ConvertStringToSystemTime(const char *dateTimeString) const
{
SYSTEMTIME systime;
memset(&systime, 0, sizeof(systime));
// Date string should be "dd-MM-yyyy hh:mm:ss:mss"
auto u = sscanf_s(dateTimeString, "%d/%d/%d%d:%d:%d:%d:%d",
&systime.wDay,
&systime.wMonth,
&systime.wYear,
&systime.wHour,
&systime.wMinute,
&systime.wSecond,
&systime.wMilliseconds);
return systime;
}
My whole problem being is that I'm reading a date from a file, which is stored in a string variable, and I need to subtract the current Systemtime to the one read from the file.
And I was trying to sort it out by converting the string to Systemtime, and then get the difference, but after trying out this function, I keep getting that warning error which I must fix but don't know how exactly.
Use %hu instead of %d.
Explanation: The fields of SYSTEMTIME fields are of type WORD, which is defined as
typedef unsigned short WORD;
Reading type unsigned short requires %hu as described here.
In windows, WORD is defined as unsigned short, so it needs %u instead of %d.

converting from void* to int in c++

I am working in a mqtt application and when i receive the information of the payload from the mqtt broker and try to convert it from the void* that is message->payload to an int as
signed int var_1=*((int*) message->payload);
instead of converting it to the number it is converting it to another one, to see this I am using the following code:
printf("Message:%s\n",message->payload);
printf("Message:%i\n",var_1);
Which shows:
Message:-58
Message:3683629
I also thought about the payload being a string, but if I use the stoi function it gives me the error:
can not convert from ´void*´ to ´int´ with stoi function.
In C++ you can't automatically convert from const void* to const char*.
You need an explicit static cast:
int i=atoi(static_cast<const char*>(message->payload));
Notice I've used atoi() which is a C library function (#include <cstdlib>).
There's little point converting it to a std::string just to parse that to an int.
All this assumes you're correct to think the payload is a character encoded decimal integer in a c-style string.
[I] try to convert it from the void* ... to an int.
OK. The first step is to figure out the type of object that is being transported. As the documentation of MQTT says:
MQTT is data-agnostic and it totally depends on the use case how the payload is structured. It’s completely up to the sender if it wants to send ...
as
signed int var_1=*((int*) message->payload);
Now, this is correct, if the pointer points to an object of type int. It is a reasonable guess, but you should not be guessing - except as last resort - for the type of the object. You should study the sender whether by reading documentation or code to find out the type of the pointed object.
instead of converting it to the number it is converting it to another one
So, either you've been expecting the wrong value, or you guessed the type wrong. The solution is to stop guessing and find out the correct type.
I also thought about the payload being a string, but if I use the stoi function it gives me the error:
can not convert from ´void*´ to ´int´ with stoi function.
The error seems to be exceptionally clear. The argument of stoi is const std::string& str, not void*. void* is not implicitly convertible to std::string. Exactly how to do such conversion depends on what type of object void* points to (or sometimes, what type of data it contains).
I didn't quite understand if message->payload holds the number itself or a string representation for it.
If message->payload holds the memory location in which the number is stored, so var_1 holds the value.
Therefore, you cannot expect those values to be the same.
Regarding stoi - it receives a string that hold number, but as a string. For example -
std::string num = "1234";
int convertedNumber = stoi(num);

Strings of unsigned chars

Here's an interesting one. I'm writing an AES encryption algorithm, and have managed to get it making accurate encryptions. The trouble comes when I attempt to write the result to a file. I was getting files with incorrect output. Hex values would be mangled and it was just generally nonsensical (even by encrypted standards).
I did some debugging by sampling my encryption output before sending it to the file. What I found was that I was getting some type of overflow somewhere. When the correct hex value was supposed to be 9e, I would get ffffff9e. It would do this only to hex values above 7F, i.e. characters in the "extended" character set weren't being handled properly. This had happened to me earlier in my project as well, and the problem then had been using a char[][] container instead of an unsigned char[][] container.
My code uses strings to pass the encrypted data between the user interface and AES encryption class. I'm guessing that std::strings don't support the extended character set. So my question is: is there a way to instantiate an unsigned string, or will I have to find a way to replace all of my usage of strings?
std::string is really just a typedef, something like:
namespace std {
typedef basic_string<char> string;
}
It's fairly easy to create a variant for unsigned char:
typedef basic_string<unsigned char> ustring;
You will, however, have to change your code to use a ustring (or whatever name you prefer) instead of std::string though.
Depending on how you've written your code, that may not require editing all the code though. In particular, if you have something like:
namespace crypto {
using std::string;
class AES {
string data;
// ..
};
}
You can change the string type by changing only the using declaration:
namespace unsigned_types {
typedef std::basic_string<unsigned char> string;
}
// ...
namespace crypto {
using unsigned_types::string;
class AES {
string data;
};
}
Also note that different instantiations of a template are entirely separate types, even when the types over which they're intantiated are related, so the fact that you can convert implicitly between char and unsigned char doesn't mean you'll get a matching implicit conversion between basic_string<char> and basic_string<unsigned char>.
std::string is nothing more or less than a specialization of the std::basic_string<> template, so you can simply do a
typedef std::basic_string<unsigned char> ustring;
to get what you want.
Note that the C/C++ standards do not define whether char is the signed or the unsigned variety, so any program that casts a char directly to a larger type invokes implementation defined behaviour.
Cast your value to unsigned char first:
char input = 250; // just an example
unsigned int n = static_cast<unsigned char>(input); // NOT: "unsigned int n = input;"
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
The problem is that your char happens to be signed, and so its value is not the "byte value" that you want -- you have to convert to unsigned char to get that.

Typecast an unsigned int to unsigned long int C++

I am kinda new to programming. I have this problem. I have a variable
unsigned long address;
I'm using
fscanf(pFile, "%x\n", &address);
to read this data from a file. The file has it in Hex(without 0x) and this converted it to Decimal and stored. So i am kind of reluctant to change this part. When I compile using g++, it is asking me to change address to
unsigned int address;
Now, this "address" variables is used in a function that I will call that has the parameter as "unsigned long". So, if I "address" to "unsigned int", how do I call this function
function(address);
such that the address is typecasted into unsigned long
When passing an address to fscanf() the type has to match the format specifier exactly. When you use %x you state you are going to pass a pointer to an unsigned int. If you feel you want to pass a pointer to an unsigned long instead, you'll need to use the format specifier %lx instead:
if (fscanf(pFile, "%lx", &address) == 1) {
// ...
}
(I can't use input functions without also checking that the input was successful...).
You are approaching the problem from the wrong direction.
When operating on pointers, you can't just alias an object through a pointer to a different type. The %x conversion specifier instructs scanf() to take an unsigned int *, so you will get undefined behavior if you pass it the address of an unsigned long. If you want to scan an unsigned long, then use the appropriate modifier:
unsigned long address;
scanf("%lx", &address);
However, if you do want to change address to be an unsigned int, then you don't have to do anything else -- the unsigned int will be implicitly converted to the appropriate type (unsigned long in this case) when passed to a function. There's no need for any kind of typecasting whatsoever. To clarify, the following code is correct:
void foo(unsigned long n) { }
unsigned int address;
scanf("%x", &address);
foo(address); // implicit conversion happens
In C you can do as
function((unsigned long)address);

How to convert pointer value obtained via reference operator to string?

I am a beginner in C++. I am working on this project where it is required to trace the memory address. Unfortunately, this tracing function has following prototype declaration:
void TRC(uint8_t, uint8_t, uint8_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, const char*)
Now the options available for me are:
Convert this memory address (pointer value) to uint64_t type. But I've read somewhere that it is not recommended, as pointer value returned by reference operator is platform dependent and conversion of a pointer to an integer may return wrong value.
Convert this memory address to string and pass it via last parameter. In Python it was easy as we had str() function. Do we have something similar in C++ too?
Please let me know if I am inferring something wrong in my approach/understanding here.
You could use streams to convert if it does not need to be fast code.
#include <sstream>
#include <iomanip>
...
std::ostringstream os;
os << std::hex << static_cast<void*>(my_pointer);
TRC(..., os.str().c_str());
You are right in that a pointer should not be stored or passed as any integer types.
If you want to convert a pointer to a printable hexadecimal string, you can use e.g. std::ostringstream:
std::ostringstream os;
os << std::hex << static_cast<void*>(some_pointer);
std::string str = os.str();
TRC(..., str.c_str());