String inserting C++ - c++

I have been working on a program that will output a given playing card. I am using the Ace of Spades just to start out. This isn't the entire program use by no means, but this is just to see if I am on the right track.
For purposes beyond what I am about to show, I need to create a string that has "Ace of HeartsSpades" stored in it from one string that contains "Ace" and one that contains "Spades"
string toString(string myRank, string mySuit)
{
string halfCard, fullCard;
halfCard = myRank; //Ace
fullCard = halfCard.append(mySuit); //AceSpades
fullCard.insert(3, " of "); //Ace of Spades
return fullCard;
}
There is the method that I have so far. I know that not every card is going to work with a position of 3 in my fullCard.insert line, so is there another way to make this work so that this method becomes universal for all cards in a deck (jokers are not used in the deck).
I am sorry if my explanation of things were not clear.

I believe you could do something like:
string toString(string myRank, string mySuit)
{
return myRank + " of " + mySuit;
}

It's easier than that (assuming you're using std::string)
std::string toString(const std::string& myRank, const std::string& mySuit)
{
return myRank + " of " + mySuit;
}
Note that I've changed your argument to be references, which will avoid unecessary string object copies.

Related

C++ File Input/Output Outputting Numbers Instead of Chars

I have created a program that randomly assigns roles(jobs) to members of a certain house using file input / output.. It builds successfully, but when using cout and I actually see the results, I can see why the program is not working.
Here is the snippet of code I believe something is wrong with :
std::string foo = std::string("Preferences/") + std::to_string(members[random]) + "-Preferences";
cout << foo << endl;
And here is the members[random] array, it is randomly selecting members from this array and reviewing their available times and assigning them jobs based on their Preference input file.
unsigned const char members[22] =
{ 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v' };
I have created a random number picker that goes through 0-21 and assigns the value it creates to variable random. So, in essence, it is members[random] and completely random.
Here is the output I get in my terminal.
Preferences/116-Preferences
But I set the output to do Preferences/ member[random] -Preferences.
It is accessing a number and not my array chars.
I created a cout << members[random]; right below it, and every time I run the program, I get
Preferences/107-Preferences <---- A random number every time
k <---- random letter every time.
So I know it must be accessing my random functions, but assigned it to numbers! How do I fix this so my proper output can be :
Preferences/t-Preferences
Please help me, and thanks!
"The more you overthink the plumbing, the easier it is to stop up
the drain" - Scotty, Star Trek III
Declaring members to be unsigned chars does not accomplish anything useful. A simple char will suffice. std::string already implements an overloaded + operator that takes a char parameter, so it's much easier than you thought it would be:
const char members[22] = {
'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v' };
// ...
std::string foo = std::string("Preferences/") + members[random]
+ "-Preferences";
There is no ::std::to_string(char), only (among less close) ::std::to_string(int). So your character is actually converted to its numerical representation and you get your unwanted result.
Try instead
std::string foo("Preferences/");
foo = foo.append(1, members[random]).append("-Preferences");
Variant using string streams:
ostringstream oss;
oss << "Preferences/" << members[random] << "-Preferences";
// get your string via:
oss.str();

How to assign string a char array that starts from the middle of the array?

For example in the following code:
char name[20] = "James Johnson";
And I want to assign all the character starting after the white space to the end of the char array, so basically the string is like the following: (not initialize it but just show the idea)
string s = "Johnson";
Therefore, essentially, the string will only accept the last name. How can I do this?
i think you want like this..
string s="";
for(int i=strlen(name)-1;i>=0;i--)
{
if(name[i]==' ')break;
else s+=name[i];
}
reverse(s.begin(),s.end());
Need to
include<algorithm>
There's always more than one way to do it - it depends on exactly what you're asking.
You could either:
search for the position of the first space, and then point a char* at one-past-that position (look up strchr in <cstring>)
split the string into a list of sub-strings, where your split character is a space (look up strtok or boost split)
std::string has a whole arsenal of functions for string manipulation, and I recommend you use those.
You can find the first whitespace character using std::string::find_first_of, and split the string from there:
char name[20] = "James Johnson";
// Convert whole name to string
std::string wholeName(name);
// Create a new string from the whole name starting from one character past the first whitespace
std::string lastName(wholeName, wholeName.find_first_of(' ') + 1);
std::cout << lastName << std::endl;
If you're worried about multiple names, you can also use std::string::find_last_of
If you're worried about the names not being separated by a space, you could use std::string::find_first_not_of and search for letters of the alphabet. The example given in the link is:
std::string str ("look for non-alphabetic characters...");
std::size_t found = str.find_first_not_of("abcdefghijklmnopqrstuvwxyz ");
if (found!=std::string::npos)
{
std::cout << "The first non-alphabetic character is " << str[found];
std::cout << " at position " << found << '\n';
}

Passing control character to char array

This one
char *house2="JAM gain\r\n"
differs from this one:
string house, prefix="JAM ", suffix="\r\n";
cin>>house;
house = prefix + nickname + suffix;
char house2[100];
strncpy(house2, house.c_str(), sizeof(house));
return house2;
Even though I type "gain" on keyboard, I need to pass this char array with control-characters to api because without them it seems it's not working. what can I do to solve problem?
Ok real code:
string nickname, prefix="NICK ", suffix="\r\n";
cout<<"Choose nickname\n";
cin>>nickname;
nickname = prefix + nickname + suffix;
cout<<nickname;
char nick[100];
strncpy(nick, nickname.c_str(), sizeof(nickname));
return nick;
sizeof is not doing what you think. Instead of
strncpy(nick, nickname.c_str(), sizeof(nickname));
you want
strncpy(nick, nickname.c_str(), nickname.size());
But even then you open yourself up to buffer-overflow, so you really want
strncpy(nick, nickname.c_str(), sizeof(nick));
Next problem is that nick is local to your function so returning it is going to "cause bad things". You could make it static (and then run into complex problems with threads later...) or you could pass it in as an argument (which would then mean you couldn't use sizeof, for technical reasons). What you really need is something a lot simpler - just return the string, not the C string.
string getNick() {
string nickname, prefix="NICK ", suffix="\r\n";
cout<<"Choose nickname\n";
cin>>nickname;
nickname = prefix + nickname + suffix;
cout<<nickname;
return nickname;
}
And just to show that it really is doing what its supposed to be, here's a working online version. Here's its full code for posterity:
#include <iostream>
#include <string>
std::string getNick() {
std::string nickname, prefix="NICK ", suffix="\r\n";
std::cout<<"Choose nickname\n";
std::cin>>nickname;
nickname = prefix + nickname + suffix;
std::cout<<nickname;
return nickname;
}
int main() {
std::string nick = getNick();
std::cout<<"in main nick = '"<<nick<<"'"<<std::endl;
}
Input
gain
.
Output
Choose nickname
NICK gain
in main nick = 'NICK gain
'
Since you have an API that takes a C string, you'll need to check the details for that api for ownership of the C-string - there are two options.
The API takes ownership of the C string and will dealloc it later.
The API makes a copy of the C string, and you control its lifetime.
In the first case you need to do this: (I'm assuming a C api, which will eventually free the passed in pointer - if its a badly designed C++ API which will delete[] it, you need to replace the malloc with a new char[nick.size()]
string nick = getNick();
char * buffer = (char*)malloc(nick.size()+1);
memcpy(buffer, nick.c_str(), nick.size());
buffer[nick.size()]=0;
your_api(buffer);
In the second case you can simply do
your_api(getNick().c_str());
Your code should be
string house, prefix="JAM ", suffix="\r\n";
string nickname;
cin>>nickname;
house = prefix + nickname + suffix;
char house2[100];
strncpy(house2, house.c_str(), sizeof(house2));
//or strncpy(house2, house.c_str(), house.length());
return string(house2);
Do not return house2 as char* as the memory will be destroyed once the function exits.
PROBLEM SOLVED (why? :P )
string prawniczek=choosenick();
int TempNumOne=prawniczek.size();
char niczek[40];
for (int a=0;a<=TempNumOne;a++)
{
niczek[a]=prawniczek[a];
}
ok problem was solved by simple rewriting chars at index position one by one
it has to mean that
strncpy with nickname.c_str() works different.
anyway - i think that way is not elegant, even though it works
does anyone know how to do it in correct way?
UPDATE:
moreover:
when the loop is in main at translate to char array from choosenick() method it works perfectly, but when i do it inside method choosenick() and return translated loop result to main it doesn't work

delete a char in a string

I need to delete a specified location in a string
For example:
input: 4 Flower
output: Floer
I wrote this code but it gave an output: Flo (i.e. erased the rest of the word)
What other function, instead of erase, can I use to achieve this objective?
int main(){
int num;
int index = 1;
string s;
cin >> num >> s;
s = s.erase(num-1);
cout << index << " " << s << endl;
return 0;
}
Try:
s.erase(num-1, 1);
You are currently (effectively) calling:
s.erase(num-1, npos);
(and remove the s = bit as there is no need to reassign s).
If you are a beginner in C++ world, I would suggest you to write your own function that does it! You may use standard functions and classes anytime you would need. Some may say, why to re-invent the wheel, but its not about re-invention, but learning what invention mean, what wheel is, and how it was invented.
Writing our own code (specially for C-strings!) will give your very good programming experience, will give confidence about syntax, and most imporatantly it will enhance your logic development skills.
Your function may be like:
void RemoveCharacter(char* pString, char cCharToRemove);
Now, the question is: will it remove all occurrences of same character, or just the first one? What if there are no occurrence of given character?
Should this function return something, if it removed character, or a counter of removals? Should it take another parameter, which says "remove-all-occurrences" or not.
Happy coding!
How about this?
std::string removeChar(std::string const& input, size_t pos) {
return input.substr(0, pos-1) + input.substr(pos);
}
or this
std::string removeChar(std::string const& input, size_t pos) {
return input.erase(pos-1, 1);
}
just try
s.erase(num-1, 1), this is what you want.
The prototype of std::string::erase is
erase(size_t __pos = 0, size_t __n = npos)
If the second parameter is not supplied, the default value npos will be used and the remainder started from __pos will be removed.

double to string in c++

I'm trying to convert the expression "5 + b * 18" to "5+16.89*18". My problem is inside the while loop. I managed to remove the spaces.
My code:
double number = 16.89;
size_t found;
ostringstream converted;
string str ("5 + b * 18");
str.erase(remove(str.begin(),str.end(),' '),str.end());
found = str.find_first_of (VALID_CHARS);
while (found != string::npos)
{
converted << fixed << setprecision (8) << number;
str.insert(found, converted.str());
found = str.find_first_of (VALID_CHARS,found + 1);
}
Can anyone help me?
Ty
insert() will shift the contents of the string to the right after the inserted text, but does not delete the character at the given position. You should use replace(), specifying a size of ` (to replace just a single character)
Is this homework? If not, I'd really advice against doing this kind of parsing yourself. There are dedicated libraries for this kind of things which have been extensively tested, such as muParser.
Use sprintf. It's great for converting most primitive types into strings.
int main()
{
double number = 16.89;
char buffer [50];
sprintf(buffer, "5 + %f * 18",number);
}