C++, best way to change a string at a particular index - c++

I want to change a C++ string at a particular index like this:
string s = "abc";
s[1] = 'a';
Is the following code valid? Is this an acceptable way to do this?
I didn't find any reference which says it is valid:
http://www.cplusplus.com/reference/string/string/
Which says that through "overloaded [] operator in string" we can perform the write operation.

Assigning a character to an std::string at an index will produce the correct result, for example:
#include <iostream>
int main() {
std::string s = "abc";
s[1] = 'a';
std::cout << s;
}
For those of you below doubting my IDE/library setup, see jdoodle demo: http://jdoodle.com/ia/ljR, and screenshot: https://imgur.com/f21rA5R
Which prints aac. The drawback is you risk accidentally writing to un-assigned memory if string s is blankstring or you write too far. C++ will gladly write off the end of the string, and that causes undefined behavior.
A safer way to do this would be to use string::replace: http://cplusplus.com/reference/string/string/replace
For example
#include <iostream>
int main() {
std::string s = "What kind of king do you think you'll be?";
std::string s2 = "A good king?";
// pos len str_repl
s.replace(40, 1, s2);
std::cout << s;
//prints: What kind of king do you think you'll beA good king?
}
The replace function takes the string s, and at position 40, replaced one character, a questionmark, with the string s2. If the string is blank or you assign something out of bounds, then there's no undefined behavior.

Yes. The website you link has a page about it. You can also use at function, which performs bounds checking.
http://www.cplusplus.com/reference/string/string/operator%5B%5D/

Yes the code you have written is valid. You can also try:
string num;
cin>>num;
num.at(1)='a';
cout<<num;
**Input**:asdf
**Output**:aadf
the std::replace can also be used to replace the charecter. Here is the reference link http://www.cplusplus.com/reference/string/string/replace/
Hope this helps.

You could use substring to achieve this
string s = "abc";
string new_s = s.substr(0,1) + "a" + s.substr(2);
cout << new_s;
//you can now use new_s as the variable to use with "aac"

Related

How to get letter from String by index? C++

Can someone briefly explain how to get a character from index from String in C++.
I need to read the first 3 letters of a String and in java it would bestr.charAt(index) and I have been searching the internet for a solution for 2h now and still don't understand...
can some one please give me an example.
std::string provides operator[] to access a character by index:
https://en.cppreference.com/w/cpp/string/basic_string/operator_at
Example:
const std::string s("hello");
const char c = s[0];
// c is set to ‘h’
substr()
It returns a newly constructed string object with its value initialized to a copy of a substring of this object.
Syntax
substr(pos, pos+len)
Code
std::string str ("Test string"); //string declaration
string sub_string = str.substr(0,3);
String index starts from 0.
Best place to look would be cpluspluc.com: http://www.cplusplus.com/reference/string/string/
You may use as earlier mentioned: http://www.cplusplus.com/reference/string/string/operator[]/
std::string str ("Test string");
for (int i=0; i<str.length(); ++i)
{
std::cout << str[i];
}
Or better yet: http://www.cplusplus.com/reference/string/string/at/
std::cout << str.at(i);
which also checks for a valid position and throws an out of range exception otherwise.
Alternatively you could use http://www.cplusplus.com/reference/string/string/data/
to acces the raw data.
Or if you want to check that your string starts with a specific pattern: http://www.cplusplus.com/reference/string/string/rfind/
std::string str = "Hey Jude!";
if (str.rfind("Hey", 0) == 0) {
// match
}
Another option to obtain a single character is to use the std::string::at() member function. To obtain a substring of a certain length, use the std::string::substr member function.

How do I find character in string and after that I extract the rest of string in C++

So my problem is next:
I have youtube link entered as input, and I should print youtubeID as output.
So, perhaps I have this link: https://www.youtube.com/watch?v=szyKv63JB3s , I should print this "szyKv63JB3s", so I came to conclusion that I need to find that " = " in user inputed string and I should look to make new string called "ytID" or "result" and store youtubeID from the moment I find that " = " characther.
So I really don't have idea how should it be done...
I mean I should go through string with for loop I guess, and after that I should store the part which will be called youtubeID, and I have problem there because I don't know how long is that link, I mean how much characthers it have, so I cannot really use for or while loops...
P.S This is not HOMEWORK, I just want to practice. :)
you should give a look at this post :
Removing everything after character (and also character)
A solution could be as simple as :
theString.substr( theString.find('=') ) ;
Just search for the character = as you mentioned in the question:
#include <iostream>
#include <string_view>
std::string_view extractYoutubeId(std::string_view const link) {
auto const off = link.find('=');
if (off == std::string_view::npos)
return std::string_view{};
return link.substr(off + 1);
}
int main() {
auto const& link = "https://www.youtube.com/watch?v=dQw4w9WgXcQ";
std::cout << extractYoutubeId(link);
}
Output: dQw4w9WgXcQ

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.

Parsing a string by a delimeter in C++

Ok, so I need some info parsed and I would like to know what would be the best way to do it.
Ok so here is the string that I need to parse. The delimeter is the "^"
John Doe^Male^20
I need to parse the string into name, gender, and age variables. What would be the best way to do it in C++? I was thinking about looping and set the condition to while(!string.empty()
and then assign all characters up until the '^' to a string, and then erase what I have already assigned. Is there a better way of doing this?
You can use getline in C++ stream.
istream& getline(istream& is,string& str,char delimiter=’\n’)
change delimiter to '^'
You have a few options. One good option you have, if you can use boost, is the split algorithm they provide in their string library. You can check out this so question to see the boost answer in action: How to split a string in c
If you cannot use boost, you can use string::find to get the index of a character:
string str = "John Doe^Male^20";
int last = 0;
int cPos = -1;
while ((cPos = str.find('^', cPos + 1)) != string::npos)
{
string sub = str.substr(last, cPos - last);
// Do something with the string
last = cPos + 1;
}
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "This is a sample string";
char * pch;
printf ("Looking for the 's' character in \"%s\"...\n",str);
pch=strchr(str,'s');
while (pch!=NULL)
{
printf ("found at %d\n",pch-str+1);
pch=strchr(pch+1,'s');
}
return 0;
}
Do something like this in an array.
You have a number of choices but I would use strtok(), myself. It would make short work of this.