Treat c++ string as a pointer - c++

Disclaimer -- I'm coming from a pretty strictly C background.
How can the STL and std::string instead of char* be used to go about jumping around a string like this (admittedly nonsensical) example?
const char* s = "XXXXXXXXhello";
while (*s == 'X')
s++;
s += 2;
std::cout << --(--s); //prints `hello`

If what you want to do is modify the object, and get rid of "h":
std::string s = "hello";
s = s.substr(1); // position = 1, length = everything (npos)
std::cout << s; //"ello"
or
std::string s = "hello";
s.erase(0, 1); // position = 0, length = 1
std::cout << s; //"ello"

perfer #José 's second answer and no need to modify the original str
just std::cout<<s.substr(1)<<endl
to the edited question:
std::string s = "hello world!";
cout<<s.substr(s.find_first_of('e'))<<endl; // == "ello world!"
man std::string:
http://www.cplusplus.com/reference/string/string/?kw=string

If you want to jump around without modifying the string, you can either use indices or an iterator:
std::string const s("XXXXXXXXhello");
int idx = 0;
while ( s[idx] == 'X' )
++idx;
idx += 2;
std::cout << &s[idx -= 2] << '\n';
The iterator version:
auto it = s.begin();
while (*it == 'X')
++it;
it += 2;
std::cout << &*it << '\n';
Since C++11 it is guaranteed that std::string is stored with null terminator in place, so you can use & to output the tail of the string. In old code bases you will need to index from s.c_str() instead.

Related

How to replace "ta" in a string "potato" in c++? 2 characters for 1

Here is the code:
string msg;
niceArray = txtReader("chatTest/replaces.txt");
vector<vector<string>>vMaster;
if(vMaster.size() <1){
string arr[] = { "a","A","á","#","à","â","ã","ÃÃ","€Ã","ƒÃ"};
vector<string> tempA(arr, arr+4);
vMaster.push_back(tempA);//"aAá#àâãÃÀÃÂ"
}
string ex;
while(sstr.good()){
sstr>>ex;
vectorCheck.push_back(ex);
}
for(int e = 0; e < vectorCheck.size(); e=e+1){
//if(e > vectorCheck[e].length()) break;
auto str = vectorCheck[e];
for(int b = 0; b < vMaster.size(); b=b+1){
for(int j=0; vMaster[b].size(); j=j+1){
//int f = str.find(vMaster[b][j]);
if(str.find(vMaster[b][j]) != std::string::npos){
int f = str.find(vMaster[b][j]);
//if(vMaster[b][j].length() > 1){
str.replace(f,2,vMaster[b][0]);
//break;
// }
//
}
}
}
for(int i = 0; i < xingArray.size(); i=i+1){
if(str == xingArray[i]){
vectorCheck[e] = niceArray[rand() % niceArray.size()];
}
}
}
So for each sentence i type i am checking each word and looking if there is any of that string arr characteres in it, if there is i replace it for the vector[0] in this case "a".
The problem is that this line str.find(vMaster[b][j]) != std::string::npos never returns me -1... Even when i type like "c" in finds c in there or "f" or any word and i get an error. The funny stuff is that when i type like "á" that turns into "Ã|" it works and with the "ã" that turns into "ã" it doesnt give me 0 again... I really dont know whats going on... I really tried hard here and if anyone has any opinion i would like to hear thanks.
std::string str ("potato.");
std::string str2 ("ta");
std::size_t found = str.find(str2);
if ( found != std::string::npos)
std::cout << "first 'ta' found at: " << found << '\n';
str.replace( found, 2, "");
I dont think C++ has any single method to find and replace so why not use inbuilt find and then replace.
For example:
void find_and_replace(string& source, string const& find, string const& replace)
{
for(std::string::size_type i = 0; (i = source.find(find, i)) != std::string::npos;)
{
source.replace(i, find.length(), replace);
i += replace.length() - find.length() + 1;
}
}
int main()
{
string text = "potato";
find_and_replace(text, "ta", "");
cout << "After one replacement: " << text << endl;
find_and_replace(text, "te", "");
cout << "After another replacement: " << text << endl;
return 0;
}

How do I get part of a char*?

I have the following code that solves a small image using Tesseract.
char *answer = tess_api.GetUTF8Text();
I know beforehand that the result will always start with the character '+' and it's one word so I want to get rid of any junk it finds.
I get the result as "G+ABC S\n\n" and I need only +ABC. So basically I need to ignore anything before + and everything after the first space. I was thinking I should use rindex to find the position of + and spaces.
std::string ParseString(const std::string& s)
{
size_t plus = s.find_first_of('+');
size_t space = s.find_first_of(" \n", plus);
return s.substr(plus, space-plus);
}
int main()
{
std::cout << ParseString("G+ABC S\n\n").c_str() << std::endl;
std::cout << ParseString("G +ABC\ne\n").c_str() << std::endl;
return 0;
}
Gives
+ABC
+ABC
If you really can't use strings then something like this might do
char *ParseString2(char *s)
{
int plus,end;
for (plus = 0 ; s[plus] != '+' ; ++plus){}
for (end = plus ; s[end] != ' ' && s[end] != '\n' ; ++end){}
char *result = new char[end - plus + 1];
memcpy(result, s + plus, end - plus);
result[end - plus] = 0;
return result;
}
You can use:
// just scan "answer" to find out where to start and where to end
int indexStart = // find the index of '+'
int indexEnd = // find the index before space
int length = indexEnd-indexStart+1;
char *dataYouWant = (char *) malloc(length+1); // result will be stored here
memcpy( dataYouWant, &answer[indexStart], length );
// for example answer = "G+ABC S\n\n"
dataYouWant[length] = '\0'; // dataYouWant will be "+ABC"
You can check out Strings in c, how to get subString for other alternatives.
P.S. suggestion: use string instead in C++, it will be much easier (check out #DavidSykes's answer).

Reverse order of hex std::string

I'm working with an old program and need help swapping the order of a Hex String.
Yes, a string...as in:
string hexString = "F07D0079"
string hexString2= "F07F"
I need each string to look like:
79007DF0 &
7FF0 respectively.
For the love of god i don't know why they're stored in strings, but they are.
This is a little endian/big endian issue but since it's in a string i can't use standard functions to reverse the order can I?
Is there any easy way to do this?
std::string swapValues(string originalHex)
{
string swappedHex;
//what to do here.
return swappedHex;
}
First check that the length is even (if it hasn't already been sanitised):
assert(hex.length() % 2 == 0);
Then reverse the string:
std::reverse(hex.begin(), hex.end());
Now the bytes are in the correct order, but the digits within each are wrong, so we need to swap them back:
for (auto it = hex.begin(); it != hex.end(); it += 2) {
std::swap(it[0], it[1]);
}
I might use the append member function.
std::string reverse_pairs(std::string const & src)
{
assert(src.size() % 2 == 0);
std::string result;
result.reserve(src.size());
for (std::size_t i = src.size(); i != 0; i -= 2)
{
result.append(src, i - 2, 2);
}
return result;
}
(As an exercise in extensibility, you can make the "2" a parameter, too.)
If you want to do it in-place, you can use std::rotate in a loop.
I wouldn't bother with something overly clever for this:
std::string swapValues(const std::string& o)
{
std::string s(o.length());
if (s.length() == 4) {
s[0] = o[2];
s[1] = o[3];
s[2] = o[0];
s[3] = o[1];
return s;
}
if (s.length() == 8) {
// left as an exercise
}
throw std::logic_error("You got to be kidding me...");
}
There should be library functions available (a naive string manipulation might be no good):
#include <iostream>
#include <arpa/inet.h>
int main() {
std::string hex32 = "F07D0079";
std::string hex16 = "F07F";
std::uint32_t u32 = std::strtoul(hex32.c_str(), 0, 16);
std::uint16_t u16 = std::strtoul(hex16.c_str(), 0, 16);
// Here we would need to know the endian of the sources.
u32 = ntohl(u32);
u16 = ntohs(u16);
std::cout << std::hex << u32 << ", " << u16 << '\n';
}
Linux/Little Endian
Any function operating on the strings must know the target platform (hence there is no general solution)

Is there a way to put strings in the `string.insert("", "")` function?

So here's the line of my code to which I'm referring:
x.insert("a", "hello");
I'm trying to insert the string "hello" after each "a" in a string. Is it possible to do this with the insert function?
is it not possible to do this with the insert function?
That's right, you can't do this with a single call to insert() since std::string does not have an insert() function with these semantics.
Following this comment, here is how you can do this in a (non-infinite) loop:
void insert_after_each(std::string& s, const std::string& target, const std::string& to_insert)
{
for (std::string::size_type i = s.find(target);
i != std::string::npos;
i = s.find(target, i + target.size() + to_insert.size()))
{
s.insert(i + target.size(), to_insert);
}
}
This inserts the text after (what I call) the target string and skips past the target text ("a") and the inserted text ("hello") in each iteration.
Sample usage:
std::string s = "A cat sat on a mat";
insert_after_each(s, "a", "hello");
assert(s == "A cahellot sahellot on ahello mahellot");
What you want to do is find the position of a by using std::string::find then call std::string::insert to insert string to the right position. For example:
C++11
auto pos = x.find("a");
x.insert(pos, "app");
C++03:
std::string b(x);
int n = 0;
for(std::string::iterator iter = x.begin(); iter!=x.end(); ++iter)
{
if ((*iter) == 'a')
{
int pos = rep.size()* n + distance(x.begin(), iter);
cout << distance(x.begin(), iter) << " " << rep.size() << endl;
b.insert(pos,"app");
n++;
}
}
Now string b is what you are after.

Removal of special character in string in C++

I have the followoing
string myStr = "myname-abc";
string myStr1 = strstr(myStr.c_str(), "-");
now in myStr1 i have -abc. But i don't want "-" infront of it i want to have "abc" how do i do that using string data type.
Thanks for help.
Not sure if I'm following, but you want to erase the first element?
str.erase(0, 1); // erases 1 element starting from position 0
Also, if you just want to erase everything up to -:
str.erase(0, str.find('-') + 1);
If the data you are feeding the program isn't guaranteed to have a - somewhere, you should check the return value of str.find('-') for string::npos, the return value when no occurence is found.
string myStr1 = strstr(mStr.c_str(), "-") + 1;
or if you want to avoid converting to C style strings:
string myStr1(m_Str, m_Str.find('-') + 1);
size_t pos = myStr.find('-');
if (pos != std::string::npos)
{
myStr1 = myStr.substr(pos + 1);
}
This program outputs
abc abc
int main()
{
string myStr = "myname-abc";
string myStr1 = strstr(myStr.c_str(), "abc");
int index = 0;
while(myStr[index++] != '-'){}
string myStr2 = myStr.substr(index);
cout << myStr1 << " " << myStr2 << endl;
return 0;
}
std::string myStr("myname-abc");
std::string myStr1(++std::find(myStr.begin(), myStr.end(), '-'),
myStr.end());
If I understand what you are asking for, it's to remove instance of "-" from the string? If so, the following will also work..
string foo("-abc");
string::size_type fm = foo.find('-');
while (fm != string::npos)
{
foo.erase(foo.begin() + fm);
fm = foo.find('-', fm); // find the next instance of "-"
}
#include<iostream.h>
#include<conio.h>
void main()
{
clrscr();
char a[30];
cout<<"enter any string ";
cin.get(a,30);
char b[30];
for(int i=0;a[i]!='\0';i++)
{
if(a[i]!='!' && a[i]!='#'&& a[i]!='#' && a[i]!='$' && a[i]!='%' && a[i]!='^' && a[i]!='&' && a[i]!='*' && a[i]!='?')
{
b[i]=a[i];
cout<<b[i];
} }
getch();
}