i have a big problem and i dont know how to fix it...
I want to decode a very long Base64 encoded string (980.000 Chars) but every time when i to debug it i get this error :
Error C2026: string too big, trailing characters truntraced
I tried this but i can only compare 2 strings throught this method
char* toHash1 = "LONG BASE 64 Code";
char* toHash2 = "LONG BASE 64 Code";
if (true) {
sprintf_s(output, outputSize, "%s", base64_decode(toHash1 =+ toHash2).c_str());
}
Anyone know how i can get it to work?
As documented here, you can only have about 2048 characters in a string literal when using MSVC. You can get up to 65535 characters by concatenation, but since this is still too short, you cannot use string literals here.
One solution would be reading the string from a file into some allocated char buffer. I do not know of any such limits for gcc and clang, so trying to use them instead of MSVC could solve this too.
You can first convert your string to hex and then can include it like this,
char data[] = {0xde,0xad,0xbe,0xef}; //example
And than can use it like a string, append null terminator if needed to.
Related
I'm trying to ask the user to enter a random word, but when I go to try to store it, the normal cin isn't working and just seems to be confusing ncurses. I've tried other functions like wgetstr() but it takes a char and not a string. I've been attempting multiple conversion functions like c_str() but nothing. Does anybody have any tips?
getstr() family of functions do return null-terminated strings, not just a single character. It's C library, there isn't any std::string type.
You must supply a suitable large buffer for the functions. It is more safe to use getnstr which limits the number of read characters.
char buffer[256];
int result = getnstr(buffer,sizeof(buffer)-1);//Make space for '\0'
assert(results!=-1);
buffer[sizeof(buffer)-1] = '\0'; // Force null-termination in the edge case.
size_t length = strlen(buffer);
I am not 100% sure whether the limit on n read characters includes the null byte, if it works as strncpy, it might not and in that case it's better to leave a space for it and add it explicitly.
This can be marked solved. The problem was the print macro. ESP_LOGx can't put out c++ Strings.
I'm trying to convert an uin8_t array to a string in c++.
The array is defined in a header file like this:
uint8_t mypayload[1112];
Printing the array itself works, so I'm sure it's not empty.
now I'm trying to convert it to a string:
string qrData;
std::string qrData(reinterpret_cast<char const*>(mypayload), sizeof mypayload);
I also tried:
qrData = (char*)mypayload;
printing the string results in 5 random chars.
Does anybody have hint where I made a mistake?
The only correct comment so far is from Some programmer dude. So all credits go to him.
The comment from Ian4264 is flat wrong. Of course you can do a reinterpret_cast.
Please read here about the constructors of a std::string. You are using constructor number 4. The description is:
4) Constructs the string with the first count characters of character string pointed to by s. s can contain null characters. The length of the string is count. The behavior is undefined if [s, s + count) is not a valid range.
So, even if the string contains 0 characters, the C-Style string-"terminator", all bytes of the uint8_t arrays will be copied. And if you print the string, then it will print ALL characters, even the none printable characters after the '\0'.
That maybe your "random" characters. Because the string after your "terminator" does most probably contain uninitialized values.
You should consider to use the constructor number 5
5) Constructs the string with the contents initialized with a copy of the null-terminated character string pointed to by s. The length of the string is determined by the first null character. The behavior is undefined if [s, s + Traits::length(s)) is not a valid range.
And if you need to add bytes, also possible. The std::string can grow dynamically.
BTW: you do define your "std::string qrData" double, which will not compile
Since you know the size of your data in another variable, why are you using sizeof? It will give you the size of the array, not the size of your data.
This should give you the right result, assuming no other errors in your code
std::string qrData(reinterpret_cast<char const*>(mypayload), data->payload_len);
Incidentally in the code you quoted why is qrData declared twice? That seems a bit suspicious.
qrData = (const char*)mypayload;
string is accept only const char*.
String s = String((char *)data, len); //esp32
I have a code that works just fine when compiled with the build tools v110. Recently I have upgraded the toolchain to v141 (vs 2k17) and some functions that made use of sscanf is not working anymore.
The sscanf calls that stopped working make use of this particular format string: "%s %[^\0]". It expects a stream string containing 1 string followed by a whitespace and another string which have to be put in a buffer for later treat. The first string is copied to the first buffer correctly but the second is not (sscanf returns 1 instead of 2).
Someone having this problem or have any idea of why it is happening?
A code sample to test the problem:
#include <stdio.h>
#include <tchar.h>
int main()
{
char str1[100], str2[100];
memset(str1, 0, sizeof(str1)); memset(str2, 0, sizeof(str2));
int i = sscanf("+nf foo", "%s %[^\0]", str1, str2);
return 0;
}
The sequence \0 encodes a zero byte (ASCII character NUL), which in C/C++ is a string terminator.
So your formatting string is effectively "%s %[^" with another one-char long string "]" possibly following it (possibly, because the compiler may notice the string termination and discard the unused tail).
Edit
As a string terminator, the NUL character actually can't appear in the input string (although it could appear e.g. in a file stream! I'm not sure, however, how that would be handled by fscanf()), so you need not look for it with the format specifier. If you just need to read both parts of an input string into two char arrays, just use "%s%s":
sscanf("+nf foo", "%s%s", str1, str2);
As stated by the user n.m. in the topic comments the string I was using ("%[^\0]") don't work because the char "\0" will be translated to a ASCII NUL ending the format string before the proper end of the specifier %[].
The correct string to use in this case (when you need to use the specifier %[] to read all the bytes instead of ASCII NUL) is "%[\1-\377]"
colleague(serioussly I dont use char* :) ) made a bug that reduces to this:
testVar.append('\0'); //testVar is std::string
So he basically this fixes it:
testVar.append("\0");
My question is why first one isnt legal?
Cant it be considered as 0 length 0 terminated string?
I tried going into VS10 std lib implementation to see for myself but I regretted it. :)
' creates a char literal, which is not the same as a string / char *. Some languages treat a single character as a length-1 string, but C++ defines a single character to be a primitive datatype while a string is an array of characters.
First, I'd like to say that I'm new to C / C++, I'm originally a PHP developer so I am bred to abuse variables any way I like 'em.
C is a strict country, compilers don't like me here very much, I am used to breaking the rules to get things done.
Anyway, this is my simple piece of code:
char IP[15] = "192.168.2.1";
char separator[2] = "||";
puts( separator );
Output:
||192.168.2.1
But if I change the definition of separator to:
char separator[3] = "||";
I get the desired output:
||
So why did I need to give the man extra space, so he doesn't sleep with the man before him?
That's because you get a not null-terminated string when separator length is forced to 2.
Always remember to allocate an extra character for the null terminator. For a string of length N you need N+1 characters.
Once you violate this requirement any code that expects null-terminated strings (puts() function included) will run into undefined behavior.
Your best bet is to not force any specific length:
char separator[] = "||";
will allocate an array of exactly the right size.
Strings in C are NUL-terminated. This means that a string of two characters requires three bytes (two for the characters and the third for the zero byte that denotes the end of the string).
In your example it is possible to omit the size of the array and the compiler will allocate the correct amount of storage:
char IP[] = "192.168.2.1";
char separator[] = "||";
Lastly, if you are coding in C++ rather than C, you're better off using std::string.
If you're using C++ anyway, I'd recommend using the std::string class instead of C strings - much easier and less error-prone IMHO, especially for people with a scripting language background.
There is a hidden nul character '\0' at the end of each string. You have to leave space for that.
If you do
char seperator[] = "||";
you will get a string of size 3, not size 2.
Because in C strings are nul terminated (their end is marked with a 0 byte). If you declare separator to be an array of two characters, and give them both non-zero values, then there is no terminator! Therefore when you puts the array pretty much anything could be tacked on the end (whatever happens to sit in memory past the end of the array - in this case, it appears that it's the IP array).
Edit: this following is incorrect. See comments below.
When you make the array length 3, the extra byte happens to have 0 in it, which terminates the string. However, you probably can't rely on that behavior - if the value is uninitialized it could really contain anything.
In C strings are ended with a special '\0' character, so your separator literal "||" is actually one character longer. puts function just prints every character until it encounters '\0' - in your case one after the IP string.
In C, strings include a (invisible) null byte at the end. You need to account for that null byte.
char ip[15] = "1.2.3.4";
in the code above, ip has enough space for 15 characters. 14 "regular characters" and the null byte. It's too short: should be char ip[16] = "1.2.3.4";
ip[0] == '1';
ip[1] == '.';
/* ... */
ip[6] == '4';
ip[7] == '\0';
Since no one pointed it out so far: If you declare your variable like this, the strings will be automagically null-terminated, and you don't have to mess around with the array sizes:
const char* IP = "192.168.2.1";
const char* seperator = "||";
Note however, that I assume you don't intend to change these strings.
But as already mentioned, the safe way in C++ would be using the std::string class.
A C "String" always ends in NULL, but you just do not give it to the string if you write
char separator[2] = "||". And puts expects this \0 at the ned in the first case it writes till it finds a \0 and here you can see where it is found at the end of the IP address. Interesting enoiugh you can even see how the local variables are layed out on the stack.
The line: char seperator[2] = "||"; should get you undefined behaviour since the length of that character array (which includes the null at the end) will be 3.
Also, what compiler have you compiled the above code with? I compiled with g++ and it flagged the above line as an error.
String in C\C++ are null terminated, i.e. have a hidden zero at the end.
So your separator string would be:
{'|', '|', '\0'} = "||"