I'm trying to debug some code. The function that prints debug messages to the screen expects a shortstring, but I want to pass a smallint to it somehow. This is the code I have:
dialogmsg('MapTile ' + ShortString( MyInteger ));
I get this message however when compiling the program:
Error: Illegal type conversion: "SmallInt" to "ShortString"
What am I doing wrong? Thanks.
You need to use IntToStr in sysstrh.inc.
dialogMsg('MapTile ' + IntToStr(MyInteger));
Related
In my code I use logging statements in order to better see what's going on. Sometimes I write code like the following:
int i = 1337;
// More stuff...
logger->info("i has the following value: " + i);
When compiled and executed in debug mode this does not print out i as expected (this is how it would work in Java/C# for example), it rather prints something garbled. In release mode however this might as well crash the entire application. What does the C++ standard say about appending ints to a std::string like I'm doing here?
Why does the compiler not warn me at all when I compile code invoking obvious undefined behavior like this? Am I missing something? I'm using Visual Studio 2022 (MSVC). The correct way to do the logging statement would be converting the int to a std::string explicitly:
logger->info("i has the following value: " + std::to_string(i));
However this bug easily slips through during development. My warning level is set to Level4 (/W4).
The problem is that in
logger->info("i has the following value: " + i);
you are not working with std::string. You are adding an int to a string literal, ie a const char[] array. The const char[] decays into a const char* pointer in certain contexts. In this case, the int advances that pointer forward by 1337 characters, which is way beyond the end of the string literal, and therefore undefined behavior.
You should get a better compiler that warns you about this, ie:
foo.cc:7:42: warning: offset ‘1337’ outside bounds of constant string [-Warray-bounds]
7 | foo("i has the following value: " + i);
| ^
You can use a std::string literal like this:
#include <string>
using namespace std::literals;
void foo(std::string);
void bla() {
int i = 1337;
foo("i has the following value: "s + i);
}
and then you get a "nicer" error that "std::string + int" isn't a thing in C++:
foo.cc:8:40: error: no match for ‘operator+’ (operand types are ‘std::__cxx11::basic_string<char>’ and ‘int’)
8 | foo("i has the following value: "s + i);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~
| | |
| std::__cxx11::basic_string<char> int
...
going on for 147 lines
After this, it should be obvious that what you want is this instead:
logger->info("i has the following value: "s + std::to_string(i));
Using std::string literals avoids mistakes like this, because it turns warnings (which your compiler doesn't even give) into hard errors, forcing you to write correct code. So I recommend using the s suffix for all strings.
This line is correct,
logger->info("i has the following value: " + i);
in the expression
"i has the following value: " + i
there is used the pointer arithmetic.
For example if you will write
logger->info("i has the following value: " + 6);
then this line has the same effect if to write
logger->info("the following value: ");
That is this line
logger->info("i has the following value: " + i);
is equivalent to the line
logger->info( &"i has the following value: "[i]);
What does the C++ standard say about appending ints to a std::string
like I'm doing here
In the expression there is no object of the type std::string. There is used a string literal that has just an ordinary array type that is an operand of an expression with the pointer arithmetic. In the expression the string literal is implicitly converted to a pointer to its first element of the type const char *.
I am currently in the process of writing up a C++ program that randomly chooses roles for people using file input/output.
I am almost done, and I build often to make sure my code is working and not psuedocode. I received an error on my snippet of code -
randomPrefs.open ("Preferences/"members[random]"-Preferences");
I am trying to access the text file in Preferences/foo-Preferences, and the variable is made random by some code above it. I have couted the random snippet and it works perfectly, so I need not include it here. The error I get is :
Avalon - Omnipotent.cpp:61:21: error: unable to find string literal operator 'operator""members' with 'const char [13]', 'unsigned int' arguments
And so, I have searched around for this error but have found nothing. I thought of making a mini-parentheses around it, and it resulted in a different error -
Avalon - Omnipotent.cpp:61:51: error: expression cannot be used as a function
Any help would be appreciated.
A little note down here, when not having the parentheses around it, I get a warning about my variable not being used -
Avalon - Omnipotent.cpp:39:21: warning: unused variable 'members' [-Wunused-variable]
However, the second error does not give a warning about the unused variable.
Hey is what my variable looks like:
unsigned const char members[22] =
And I assigned the value "random" which selects a random number from 0 - 21 and I assign the number generated to value random, and declare the variable as members[random]. It works perfectly, I just need help with these errors.
Help!
To concatenate strings, do the following:
std::string s = std::string("Preferences/") + members[random] + "-Preferences";
randomPrefs.open(s);
If you don't want the intermediate named variable, then:
randomPrefs.open(std::string("Preferences/") + members[random] + "-Preferences");
If members doesn't contain characters like 'A', 'B', 'C', or '4', and instead contains the number 4, 28, or 153, then you can convert the number to the appropriate string by using std::to_string.
std::string s = std::string("Preferences/") + std::to_string(members[random]) + "-Preferences");
The warning about the unused variable isn't useful, and is due to the compiler seeing earlier errors in your code. If you fix the above, that should also go away.
If you're trying to do string concatenation, it is probably best to use itoa() -> std::string(const char*) or to_string() for the number to string, and use operator+() or std::string.append() to do concatenation.
Note that to_string() is C++11:
http://coliru.stacked-crooked.com/a/eb3677d7abffca00
#include <iostream>
#include <string>
int main() {
std::string str1 = "Hello ";
int i = 2;
std::string str2 = " World!";
std::string output = "";
output.append(str1).append(std::to_string(i)).append(str2);
std::cout << output << std::endl;
return 0;
}
#YoBro: HERE! – Bill Lynch 7 mins ago
Modelling a bit of my code after his made it work!
std::string s = std::string("Preferences/") + std::to_string(members[random]) + "-Preferences";
randomPrefs.open(s);
I now use something similar to that.
I've been printing a combination of strings and numbers with Arduino's Serial.println() like:
Serial.println(((String)"some value: " + some_value);
And this seems to work for most types, but fails for floats, which give me the compilation error:
ambiguous overload for ‘operator+’ (operand types are ‘String’ and ‘float’)
I've tried different calls like:
Serial.println(((String)"some float:" + ((String)some_float));
Serial.println(((String)"some float: " + String(some_float));
Serial.println(((String)"some float: " + String(some_float, 2));
but they give similar errors. Arduino's docs on String seem to imply that these should work. What am I doing wrong?
Update
After correcting my original errors, I now have this issue:
Serial.println(String("some value: ") + String(some_value));
>> call of overloaded ‘String(float&)’ is ambiguous
I also tried:
Serial.println(String("some float: ") + String(some_float, 2));
>> call of overloaded ‘String(float&, int)’ is ambiguous
It should be something else. I tried now with an Arduino UNO this code:
float some_float;
void setup() {
Serial.begin(9600);
some_float = 13.3558;
}
void loop() {
Serial.println(String("some float: ") + String(some_float, 2));
delay(1000);
}
and the output is
some_float: 13.35
some_float: 13.35
some_float: 13.35
...
First, you have an extra open bracket in all of your tests.
Next, as the error says, you are attempting to add a float value to a String type. The docs say the + operator only supports adding two String types together.
You'll need to convert your float into a String then add the two Strings together. There is an example of this on the doc page you linked:
String stringOne = String(5.698, 3); // using a float and the decimal places
The last example you gave that gives 'similar errors' looks like it should work when you remove the extra open bracket, according to the docs.
EDIT: in reference to the new error message ">> call of overloaded ‘String(float&)’ is ambiguous" can you paste some additional code to show at least:
- the definitions of some_float and some_value
- any namespaces you are including (e.g. std etc)
Generally with these sorts of problems, you should reduce the code to the simplest example which shows the error and post that whole example in the thread. (Quite often when you reduce it to the simplest example, you learn what the problem is anyway!)
The error says that String(float&) is ambiguous, so I'm guessing you have another namespace with a String definition in it which is conflicting with the Arduino version.
I'm trying to write a code in C++ that allows you to enter some text and it will open a website with the variable s_input appended to it. However, I get this error:
'system' : cannot convert parameter 1 from 'std::string' to 'const
char *'
I get that error for the last line you see.
cin >> s_input;
transform(s_input.begin(), s_input.end(), s_input.begin(), tolower);
s_input = "start http://website.com/" + s_input + "/0/7/0";
system(s_input);
I am new to C++ and this is more of a learning program.. So please show as many examples as possible! Thanks!
If s_input is a std::string (I'm betting it is):
system(s_input.c_str());
The function system takes a const char* as parameter, as the error message clearly states.
I am struggling with the code from few days can anyone help
std::string str=uri_req1.substr(found+1);
char query[2000];
sprintf(query,"Insert into publish VALUES('%s','NO')",str);
I am getting following warnings and value is not inserted in the tables
warning: cannot pass objects of non-POD type ‘struct std::string’
through ‘...’; call will abort at runtime
warning: format ‘%s’ expects type ‘char*’, but
argument 3 has type ‘int’
other thing I tried was
string query;
query="Insert into publish values('";
query+=str;
query+="','NO')";
mysql_query(&mysql,query);
but this also never worked
kindly help
I'd probably use a stringstream to assemble the string:
std::ostringstream query;
query << "Insert into publish values('" << str << "', 'NO')";
mysql_query(&mysql, query.str().c_str());
This will surely work ;)
string query;
query="Insert into publish values('";
query+=str;
query+="','NO')";
mysql_query(&mysql,query.c_str());