I have a string
string str= "Jhon 12345 R333445 3434";
string str1= "Mike 00987 #F54543";
So from str i want "R333445 3434" only because after second space character whatever appear i want all, similarly form str1 "#F54543"
I used stringstream and extract the next word after the space but it wont give correct result for
str ="Jhon 12345 R333445 3434";
it gives R333445 only it should give "R333445 3434"
Please suggest some better logic of my problem.
How about
#include <string>
#include <iostream>
int main()
{
const std::string str = "Jhon 12345 R333445 3434";
size_t pos = str.find(" ");
if (pos == std::string::npos)
return -1;
pos = str.find(" ", pos + 1);
if (pos == std::string::npos)
return -1;
std::cout << str.substr(pos, std::string::npos);
}
Output
R333445 3434
According to http://ideone.com/P1Knbe.
It seems you want to skip the first two words and read the rest, if that is correct you can do something like this.
std::string str("Jhon 12345 R333445 3434"");
std::string tmp, rest;
std::istringstream iss(str);
// Read the first two words.
iss >> tmp >> tmp;
// Read the rest of the line to 'rest'
std::getline(iss,rest);
std::cout << rest;
You could find the index of the second space and then take the substring from one position past it to the end.
int index = 0;
for (int i = 0; i < 2; ++i){
index = (str.find(" ", index)) + 1;
}
ans = str.substr(index);
reference on std::string::find
reference on std::string::substr
Related
This question already has answers here:
How do I iterate over the words of a string?
(84 answers)
Closed 4 years ago.
I have a string of data that looks like
string line = "Number:Description:Price:Weight";
I want to separate the string into 4 different variables via the delimiter ":". I was trying this via the substring method
char delimiter = ':';
string number = line.substr(0, line.find(delimiter));
It works fine for the first variable. However, I am unable to figure out how to iterate to the next instance of the ":" for the other variables.
std::string::find() takes a starting index as an optional parameter:
string line = "Number:Description:Price:Weight";
string::size_type start, end;
char delimiter = ':';
end = line.find(delimiter);
string number = line.substr(0, end);
start = end + 1;
end = line.find(delimiter, start);
string desc = line.substr(start, end-start);
start = end + 1;
end = line.find(delimiter, start);
string price = line.substr(start, end-start);
string weight = line.substr(end + 1);
Alternatively, you can split the string on delimiters by using std::istringstream with std::getline():
string line = "Number:Description:Price:Weight";
string number, desc, price, weight;
char delimiter = ':';
istringstream iss(line);
getline(iss, number, delimiter);
getline(iss, desc, delimiter);
getline(iss, price, delimiter);
getline(iss, weight);
It is much easier with a simple for loop:
#include <iostream>
#include <vector>
int main()
{
std::string line = "Number:Description:Price:Weight";
std::vector<std::string> vecStrings;
std::string word;
size_t count = 0;
for (auto const& it : line)
{
if (it != ':') word += it;
if ((it == ':') || (count + 1 == line.size()))
{
vecStrings.emplace_back(word);
word.clear();
}
++count;
}
for(const auto& it: vecStrings)
std::cout << it << "\n";
return 0;
}
See live action: https://www.ideone.com/DiAvjO
Update: If you need something different, you can do the same thing with std::for_each() and a lambda:
#include <algorithm>
std::for_each(std::begin(line), std::end(line), [&](char &letter)
{
if (letter != ':') word += letter;
if ((letter == ':') || (count + 1 == line.size()))
{
vecStrings.emplace_back(word);
word.clear();
}
++count;
});
However, a much simpler solution to this would be to use std::istringstream. Thanks to RemyLebeau for pointing out this:
#include <sstream>
std::stringstream sstr(line);
std::string word;
while (std::getline(sstr, word, ':'))
{
vecStrings.emplace_back(word);
}
you can make use of strtok like below
#include <string.h>
int main()
{
char line[] = "Number:Description:Price:Weight";
char * token = std::strtok (line,":");
while (token != NULL)
{
cout << token << '\n';
token = std::strtok(NULL, ":");
}
return 0;
}
Make necessary changes as per your need
cstring has strtok that does exactly what you want.
I have this string: System->ONDRASHEK: Nick aaasssddd není v žádné místnosti and I need aaasssddd as output from string. Output is not the same each time. So it must be get from two whitespaces. I tried substr or split, but my knowledge of C++ is very poor.
I find this code:
#include <string>
#include <iostream>
int main()
{
const std::string str = "System->ONDRASHEK: Nick aaasssddd není v žádné místnosti";
size_t pos = str.find(" ");
if (pos == std::string::npos)
return -1;
pos = str.find(" ", pos + 1);
if (pos == std::string::npos)
return -1;
std::cout << str.substr(pos, std::string::npos);
}
But is not, what I need.
I assume you want the third word from the given string.
You have find the second space, but your output is the sub-string from the second space to the end of the string.
Instead, you need to find the third space, and output the sub-string between the two spaces.
So here is the modification.
#include <string>
#include <iostream>
int main()
{
const std::string str = "System->ONDRASHEK: Nick aaasssddd není v žádné místnosti";
size_t pos = str.find(" ");
size_t start;
size_t end;
if (pos == std::string::npos)
return -1;
pos = str.find(" ", pos + 1);
if (pos == std::string::npos)
return -1;
start = pos + 1;
pos = str.find(" ", pos + 1);
if (pos == std::string::npos)
return -1;
end = pos;
std::cout << str.substr(start, end - start) << std::endl;
}
please elaborate you question? you need substring between 2 white spaces ? if I am true, find first whitespace and then print string until you find another whitespace. you can use characters for that
#include <iostream>
#include <string>
using namespace std;
string Latin(string words)
{
string strWord, strSentence = "";
int length = 0, index = 0;
while (words[index] != '\0')
{
if(words.find(' ', index) != -1)
{
length = words.find(' ', index);
length -= index;
strWord = words.substr(index,length);
strWord.insert(length, "ay");
strWord.insert(length, 1, words[index]);
strWord.erase(0,1);
index += length +1;
}
else
{
strWord = words.substr(index);
length = strWord.length();
strWord.insert(length, "ay");
strWord.insert(length,1,words[index]);
strWord.erase(0,1);
index = words.length();
}
strSentence += (strWord + " ");
}
return strSentence;
}
int main()
{
string str;
getline(cin,str);
str = Latin(str);
cout<<str<<endl;
return 0;
}
I get this error that says
I have no clue what to do. As I am new to this, this is a program that is suppose to ask for user input of a length of words and translate them into pig Latin. Any help would be greatly appreciated.
Unless I really wanted to make my own life difficult, I'd do this quite a bit differently. First, I'd use a std::stringstream to break the input string into words to process. Then, I'd use std::rotate to move the first character of the string to the end. Finally, I'd wrap that all in std::transform to manage applying the function to each word in succession.
std::string line;
std::getline(std::cin, line);
std::stringstream buffer(line);
std::stringstream result;
std::transform(std::istream_iterator<std::string>(buffer),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(result, " "),
[](std::string s) {
std::rotate(s.begin(), s.begin() + 1, s.end());
s += "ay";
return s;
});
Of course, this doesn't know the special rules for things like words that start with vowels or letter pairs like sh or ch, but it looks like that's outside the scope of the task at hand.
For more on std::rotate, I recommend watching some of Sean Parent's videos.
for example we have in our set:
bin/obj/Debug/CloudServerPrototype/ra.write.1.tlog
bin/obj/Debug/CloudServerPrototype/rc.write.1.tlog
bin/obj/Debug/vc100.idb
bin/obj/Debug/vc100.pdb
So this is what I tried based on this grate answer:
#include <iostream>
#include <algorithm>
#include <set>
#include <string>
#include <iterator>
using namespace std;
struct get_pertinent_part
{
const std::string given_string;
get_pertinent_part(const std::string& s)
:given_string(s)
{
}
std::string operator()(const std::string& s)
{
std::string::size_type first = 0;
if (s.find(given_string) == 0)
{
first = given_string.length() + 1;
}
std::string::size_type count = std::string::npos;
std::string::size_type pos = s.find_last_of("/");
if (pos != std::string::npos && pos > first)
{
count = pos + 1 - first;
}
return s.substr(first, count);
}
};
void directory_listning_without_directories_demo()
{
set<string> output;
set<string> demo_set;
demo_set.insert("file1");
demo_set.insert("file2");
demo_set.insert("folder/file1");
demo_set.insert("folder/file2");
demo_set.insert("folder/folder/file1");
demo_set.insert("folder/folder/file2");
demo_set.insert("bin/obj/Debug/CloudServerPrototype/ra.write.1.tlog");
demo_set.insert("bin/obj/Debug/CloudServerPrototype/rc.write.1.tlog");
demo_set.insert("bin/obj/Debug/vc100.idb");
demo_set.insert("bin/obj/Debug/vc100.pdb");
std::transform(demo_set.begin(),
demo_set.end(),
std::inserter(output, output.end()),
get_pertinent_part("bin/obj/Debug/"));
std::copy(output.begin(),
output.end(),
std::ostream_iterator<std::string>(std::cout, "\n"));
}
int main()
{
directory_listning_without_directories_demo();
cin.get();
return 0;
}
This outputs:
CloudServerPrototype/
file1
file2
folder/
folder/folder/
vc100.idb
vc100.pdb
and we are given with bin/obj/Debug/string. We want to cout:
vc100.idb
vc100.pdb
CloudServerPrototype/
How to do such thing?
Quick example of what you want to do.
String.find(): http://www.cplusplus.com/reference/string/string/find/
String.subStr(): http://www.cplusplus.com/reference/string/string/substr/
string str = "bin/obj/Debug/vc100.pdb";
string checkString ("bin/obj/Debug");
// Check if string starts with the check string
if (str.find(checkString) == 0){
// Check if last letter if a "/"
if(str.substr(str.length()-1,1) == "/"){
// Output strating at the end of the check string and for
// the differnce in the strings.
cout << str.substr(checkString.length(), (str.length() - checkString.length()) ) << endl;
}
}
It's not clear with which part of the problem you are stuck, so here is a starter for you.
To get the parts of the strings between "given string" and the final '/' (where present):
std::string get_pertinent_part(const std::string& s)
{
std::string::size_type first = 0;
if (s.find(given_string) == 0)
{
first = given_string.length() + 1;
}
std::string::size_type count = std::string::npos;
std::string::size_type pos = s.find_last_of("/");
if (pos != std::string::npos && pos > first)
{
count = pos + 1 - first;
}
return s.substr(first, count);
}
To insert these parts into a new set (output) to guarantee uniqueness you can use the following:
std::transform(your_set.begin(),
your_set.end(),
std::inserter(output, output.end()),
get_pertinent_part);
You may wish to pass given_string into get_pertinent_part(), in which case you'll need to convert it to a functor:
struct get_pertinent_part
{
const std::string given_string;
get_pertinent_part(const std::string& s)
:given_string(s)
{
}
std::string operator()(const std::string& s)
{
std::string::size_type first = 0;
//
// ...same code as before...
//
return s.substr(first, count);
}
};
You can then call it this way:
std::transform(your_set.begin(),
your_set.end(),
std::inserter(output, output.end()),
get_pertinent_part("bin/obj/Debug"));
To output the new set:
std::copy(output.begin(),
output.end(),
std::ostream_iterator<std::string>(std::cout, "\n"));
Sorting the results is left as an exercise.
The easiest way I can think of, using the standard C functions, would be:
char * string1 = "bin/obj/Debug"
char * string2 = "bin/obj/Debug/CloudServerPrototype/rc.write.1.tlog"
char result[64];
// the above code is just to bring the strings into this example
char * position = strstr(string1, string2);
int substringLength;
if(position != NULL){
position += strlen(string2);
substringLength = strchr(position, '/') - position;
strncpy(result, position, substringLength);
}else{
strcpy(result, string1); // this case is for when your first string is not found
}
cout << result;
The first thing that occurs, is finding the substring, string1, in the string we are analyzing, being string2. Once we found the starting point, and assuming it was there at all, we add the length of that substring to that starting point using pointer arithmatic, and then find the resulting string's length by subtracting the starting position from the ending position, which is found with strchr(position, '/'). Then we simply copy that substring into a buffer and it's there to print with cout.
I am sure there is a fancy way of doing this with std::string, but I'll leave that to anyone who can better explain c++ strings, I never did manage to get comfortable with them, haha
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();
}