I've used cpp for quite a while, I was known that we cannot add string and numbers(as + operator is not overloaded for that). But , I saw a code like this.
#include <iostream>
using namespace std;
int main() {
string a = "";
a += 97;
cout << a;
}
this outputs 'a' and I also tried this.
string a ="";
a=a+97;
The second code gives a compilation error(as invalid args to + operator, std::string and int).
I don't want to concatenate the string and number.
What is the difference? Why does one work but not the other?
I was expecting that a+=97 is the same as a=a+97 but it appears to be different.
The first snippet works because std::string overrides operator+= to append a character to a string. 97 is the ASCII code for 'a', so the result is "a".
The second snippet does not work because there is no + operator defined that accepts a std::string and an int, and no conversion constructor to make a std::string out of an int or char. There two overloads of the + operator that take a char, but the compiler cannot tell which one to use. The match is ambiguous, so an error is reported.
Related
Trying to run this:
// appending to string
#include <iostream>
#include <string>
int
main()
{
std::string str;
std::string str2 = "Writing ";
std::string str3 = "print 10 and then 5 more";
// used in the same order as described above:
str.append(str2); // "Writing "
str.append(str3, 6, 3); // "10 "
str.append("dots are cool", 5); // "dots "
str.append("here: "); // "here: "
str.append(10u, '.'); // ".........."
str.append(str3.begin() + 8, str3.end()); // " and then 5 more"
str.append<int>(5, 0x2E); // "....."
std::cout << str << '\n';
return 0;
}
But having error on str.append(5,0x2E):
error: no matching function for call to ‘std::__cxx11::basic_string::append(int, int)’
Using VS Code 1.43.1, running on ubuntu 19.10, gcc version 9.2.1 20191008 (Ubuntu 9.2.1-9ubuntu2).
I've tried to run the code on Code::Blocks 16.01 IDE, and windows, but had same error.
You need to convert 0x2E (integer) to char: char(0x2E) first.
str.append<int>(5,char(0x2E));
When having problems with the standard template library, you can always take a look at the c++ reference of the function you're using: http://www.cplusplus.com/reference/string/string/append/
In this case, there isn't any reason to specify the after your append: When doing this, both arguments get interpreted as an int, while you want the second to be interpreted as a char. You can simply achieve this by doing str.append(5,0x2E);. Your compiler will search the closest matching function, which is string& append (size_t n, char c); and implicitly convert the second argument to a char.
You just don't need the <int> part. str.append(5, 0x2E); compiles fine.
There is no variant of std::string::append() that takes two integers - you should make the second parameter a character, as there is a variant that takes an integer and a character.
In addition, by using <int>, you change the templated character type charT into an integer rather than a character, which is probably not going to work the way you expect. A std::string is generally defined as std::basic_string<char> so appending with .append<int> is going to have weird effects on the underlying memory at best.
Since you're wanting to add five more . characters, I'm not sure why you wouldn't just do:
str.append(5, '.');
I am sorry for the simple question, but I cannot understand why this simple program does not work.
What is a[0] supposed to be other than "a"?
#include <iostream>
using namespace std;
int main(){
string a = "abcd";
string b = "a";
if (a[0]==b){//<------problem here
cout << a << endl;
}
return 0;
}
which returns the error
no match for ‘operator==’ (operand types are ‘char’ and ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’)
or simply using string c=a[0]; returns the error:
conversion from ‘char’ to non-scalar type ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’ requested
PS: after trying a few things, I can get it to work if I compare a[0]==b[0] or assign c[0]=a[0] because those are now definitely the same type, but I still would like to know what the standard and/or fastest way to carry out a comparison of a substring with another string in C++ is.
You should use std::string::find to find substrings. Using the subscript operator on string returns a single character (scalar), not a string (vector, non-scalar); therefore, they are not the same type and there is no defined comparison.
You can can also use std::string::substr to select a substring which you can directly compare against another string.
Example
#include <iostream>
#include <string>
int
main() {
std::string a = "abcd";
std::string b = "a";
if (a.find(b) != std::string::npos) {
std::cout << a << "\n";
}
if (a.substr(0, 1) == b) {
std::cout << a << "\n";
}
return 0;
}
References
http://en.cppreference.com/w/cpp/string/basic_string/find
http://en.cppreference.com/w/cpp/string/basic_string/substr
http://en.cppreference.com/w/cpp/string/basic_string
what is a[0] supposed to be other than "a"?
It is an 'a' not "a" and it is a char. You cannot compare a char to a string because they are different types. But what you can do is extract a substring from your string that is the length of 1 character:
if (a.substr(0,1)==b)...
Then you will be comparing "a" to "a" because .substr returns a string not a char, even if the length is 1.
Also don't forget to #include <string> if you are working with std::string.
a[0] is a character, which has the value 'a', whereas b is a string, which has a different type. This will work if an operator ==(char, string) is defined (or some variant with const's and/or ref's) but there isn't, at least in the C++ standard, so the compilation should fail. The clang compiler even gives the helpful message,
invalid operands to binary expression ('int' and 'string'...
which indicates that you're comparing different types.
Try changing it to compare a[0] and b[0]. The bracket operator is defined for strings, and returns a character, so you can compare them that way.
edit: This may look as if it doesn't answer the question. It does answer the original question; the OP changed the entirety of the question after the fact (and someone added a corresponding answer) but the original question is still there in the first paragraph. I'll delete the answer if moderators want.
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.
#include <iostream>
#include <string>
using namespace std;
std::string dispCard(int card)
{
string textCard = "help";
//cout << textCard;
system("pause");
return textCard;
}
int main()
{
// Using this area to test functions for now
cout << dispCard(14);
return 0;
}
Uncommenting the cout line actually does display the value. But I cannot return the value in the string.
Honestly, I have no idea why this isn't working. I initially just wanted to use "char" but that doesn't work for some reason.
Visual Studio didn't like:
char test;
test = "help";
It underlined the "=".
For now, I just want to return a string value from a function. There's more that I need it to do, but this is the main issue right now.
Uncommenting the cout line actually does display the string. But not returning the string.
Your program both prints and returns the string, printing it again in main. The only problems I can see with your program are:
You are using system("pause") for no reason.
You are not consistent with the use of either the std:: prefix or importing the namespace. On this regard I highly suggest the std:: prefix.
You are not using the function argument.
I initially just wanted to use "char" but that doesn't work for some reason.
Well, char, as the name suggests, can only store 1 characters. In:
char test = "help";
you are trying to assign 5 characters (4 + \0) to an objects who's size can only store 1. That's the reason why your compiler complained.
I think you need to pass an int to your function and get it back in string form. To do this conversion you need something like this:
std::ostringstream stm;
stm << yourIntValue;
std::string s(stm.str());
or this:
char bf[100];
sprintf(bf, "%d", yourIntValue);
std::string s(bf);
If you put this snippet in a function then you can also accept an int parameter, convert it to a std::string and return the std::string as others have shown.
What you need to do is to declare return type of function as std::string and then return either a string object, something that can implicitly be converted to string object or something that explicitly constructs string object.
Example:
std::string foo(){
return "idkfa"; //return C-style string -> implicitly convertible to string
return {"idkfa"}; // direct initialization of returning std::string
return std::string("idkfa"); //return explicitly constructed std::string object
}
Also note that C-style strings are of type char* (C-style strings are basically an array of chars, with last element being \0, that is 0).
Your code works perfectly fine, though the the system("pause") is totally redundant and pointless and should be removed. It may in fact be confusing you.
this compiles :-)
string name;
name = 1;
this does not:
string name = 1;
any thoughts?
I know that this is wrong. . . that is not the point. The first gives a smiley face.
The first compiles because the assignment operator is called what has one signature of "string& operator= ( char c )" and the compiler can convert 1 into a char.
The second won't compile because it calls the copy constructor which has no compatible signature.
The second example is really initialization rather than assignment, i. e. it calls a constructor rather than operator=. Evidently class string does not have a constructor that takes an integer as an argument, but it's assignment operator is ok with it. And the reason you get a smiley face is that it is the character with the ASCII value of 1.
By the way, this is not specific to Visual Studio. Any C++ compiler should behave the same way.
Not to do with the question, but why don't you (and many others) post compilable code. Would :
#include <string>
using namespace std;
int main() {
string name;
name = 1;
string name2 = 1;
}
have been too much to ask for? Given that, we can see that "string" actually refers to std::string and not some random class.