how to split cin input - c++

I am facing problem to split my input in C++, for something similar to the Python split function.
The input is given as 1001-43 1003-45 1008-67 in different lines. I want to know how to take these inputs split by '-' and store them in different variables.
In Python it's:
a, x = input().split('-')

Have a look at boost. The string algorithms library includes most of what you can find in python including a split function which splits a string into an stl container of your choice. For example (lifted from their docs) splitting on dash or asterisk:
std::string str1("hello abc-*-ABC-*-aBc goodbye");
std::vector< std::string > SplitVec; // #2: Search for tokens
split( SplitVec, str1, is_any_of("-*"), token_compress_on );
// SplitVec == { "hello abc","ABC","aBc goodbye" }

int number,digit1,digit2,digit3;
std::cin>>number;
digit1=number%10;
digit2=number%100;
digit3=number%1000;

Check out strtok(), http://www.cplusplus.com/reference/clibrary/cstring/strtok/

Related

Converting strings to char arrays using cstring

I have a small assignment which partly requires me to take inputs from a file in the form of strings and place them into char arrays so I can check if the string contains any '*' character at the end of it.
I have been able to extract the strings from the files successfully, however i have failed to find a way in which to place them in char arrays so i can process them.
I would be very grateful if someone would let me know how to place a string into char arrays using cstring library. Please keep in mind that the strings are taken from a file and not as user input.
some of the ways i tried is the following:
//Try 1
char CstringArray[] = LineFromFile;
//Try 2
char CstringArray[100] = LineFromFile;
//Try 3
ifstream Test("Test.txt");
Test>>CstringArray;
//Try 4
ifstream Test("Test.txt");
Test>>CstringArray[0];
Thank you very much
Since this is an assignment, your professor will probably not be happy with you using all of C++'s functionality, particularly if you don't understand it, but since it's a one liner I figured I'd tell you how I'd print all strings ending in an asterisks. Given that you have successfully opened the file to ifstream Test you can do:
copy_if(istream_iterator<string>(Test), istream_iterator<string>(), ostream_iterator<string>(cout, " "), [](const auto& i) { return !empty(i) && i.back() == '*'; })
EDIT:
I'm using an istream_iterator to read in each string in Test and istream_iterator, I'm operating on these values immediately, but if you needed to start by saving all the strings to a vector<string> you could also do this: vector<string> CstringArray{ istream_iterator<string>(Test), istream_iterator<string>() }
I'm using an ostream_iterator to directly stream out my selected strings rather than storing them
I'm using copy_if to iterate over all the strings that are streamed in, selecting only those that meet a given criteria
I'm using the lambda: [](const auto& i) { return !empty(i) && i.back() == '*'; } to conditionally select non-empty strings which end with an asterisks character

Manipulating specific position in string according to one another

I have a string which has different city names. The format like this :
string cities = "-Paris-Berlin-Cologne-"
And also there is another string which contains some voting results for these cities.
string vote = "-31.2-42.5-40-"
I need to define a function which takes input from user for ex : Berlin
Then function will find and change the result of vote in "string vote"
I tried with counting "-" separators but I couldn't succeed.
Any help would appreciate.
Thank you.
Split both strings at the separators and put the results in a map
std::vector<std::string> split(std::string const& s, std::string const& sep);
std::vector<std::string> const c = split(cities, "-");
std::vector<std::string> const v = split(votes, "-");
// now put them all in a map
assert(c.size() == v.size());
std::map<std::string, float> city2vote;
for (std::vector<std::string>::size_type i=0; i != c.size(); ++i)
{
city2vote[c[i]] = atof(v[i]);
}
// update vote for Berlin
city2vote["Berlin"] = 42.0;
The split function is strait forward, but Boost also provides an implementation if you can use libraries. I used atof for simplicity. In real life, a stringstream would be a much better choice.
Would using a regex search to find the positions in the string of the hyphens, then changing the values between those positions accordingly be an acceptable solution?
Edit - On second thoughts, you needn't overcomplicate things by using regex, you could just use a for loop to scan through the string
First I think you should map each delimited string from cities to vote. You can do it like this:
std::map<std::string, std:string> city_to_vote;
std::istringstream i1(cities), i2(vote);
for (std::string str1, str2; std::getline(i1, str1, '-') &&
std::getline(i2, str2, '-'); )
{
if (!str1.empty() && !str2.empty())
{
city_to_vote.emplace(std::make_pair(str1, str2));
}
}
Then once you receive string input from the user, check if it is inside the map, access the value that it is mapped to, and use a replace algorithm to augment the vote string.

How to cut string at various signs

I´ve got the following problem:
I read in WinCC Variables from a .csv file. Now there is a string which contains the ip address. It looks like this: I0043CTRL/CALH1$ST$Beh$stVal;Len=4;MMSType=133;Flag=RW
The Address in this example is I0043.
Now I want to cut the string after the address, but there are more possible name of the variabel, for example I0043PROT/....
Is there any possibility to tell for example getline to end at various signs?
Like: getline(tmp_stringstream,tmp_string, 'C' || 'P');
Thank you
Patrick
boost::split does what you need: http://www.boost.org/doc/libs/1_53_0/doc/html/string_algo/usage.html#idp163440592
std::string mystring("asd,ff.erw qewr");
std::vector<std::string> tokens;
boost::split( tokens, mystring, boost::is_any_of(",.-/ ") );
In C runtime library there's a string tokenizer function, strtok (include < string.h>)
In C++ runtime there's an equivalent std::strtok (include < cstring>)
You can use std::string::find_first_of, and std::string::substr:
string line("I0043CTRL/CALH1$ST$Beh$stVal;Len=4;MMSType=133;Flag=RW");
cout << line.substr(0, line.find_first_of("CP"));
output:
I0043

How to read a file and get words in C++

I am curious as to how I would go about reading the input from a text file with no set structure (Such as notes or a small report) word by word.
The text for example might be structured like this:
"06/05/1992
Today is a good day;
The worm has turned and the battle was won."
I was thinking maybe getting the line using getline, and then seeing if I can split it into words via whitespace from there. Then I thought using strtok might work! However I don't think that will work with the punctuation.
Another method I was thinking of was getting everything char by char and omitting the characters that were undesired. Yet that one seems unlikely.
So to sort the thing short:
Is there an easy way to read an input from a file and split it into words?
Since it's easier to write than to find the duplicate question,
#include <iterator>
std::istream_iterator<std::string> word_iter( my_file_stream ), word_iter_end;
size_t wordcnt;
for ( ; word_iter != word_iter_end; ++ word_iter ) {
std::cout << "word " << wordcnt << ": " << * word_iter << '\n';
}
The std::string argument to istream_iterator tells it to return a string when you do *word_iter. Every time the iterator is incremented, it grabs another word from its stream.
If you have multiple iterators on the same stream at the same time, you can choose between data types to extract. However, in that case it may be easier just to use >> directly. The advantage of an iterator is that it can plug into the generic functions in <algorithm>.
Yes. You're looking for std::istream::operator>> :) Note that it will remove consecutive whitespace but I doubt that's a problem here.
i.e.
std::ifstream file("filename");
std::vector<std::string> words;
std::string currentWord;
while(file >> currentWord)
words.push_back(currentWord);
You can use getline with a space character, getline(buffer,1000,' ');
Or perhaps you can use this function to split a string into several parts, with a certain delimiter:
string StrPart(string s, char sep, int i) {
string out="";
int n=0, c=0;
for (c=0;c<(int)s.length();c++) {
if (s[c]==sep) {
n+=1;
} else {
if (n==i) out+=s[c];
}
}
return out;
}
Notes: This function assumes that it you have declared using namespace std;.
s is the string to be split.
sep is the delimiter
i is the part to get (0 based).
You can use the scanner technique to grabb words, numbers dates etc... very simple and flexible. The scanner normally returns token (word, number, real, keywords etc..) to a Parser.
If you later intend to interpret the words, I would recommend this approach.
I can warmly recommend the book "Writing Compilers and Interpreters" by Ronald Mak (Wiley Computer Publishing)

Translating Program

I am beginning to write a translator program which will translate a string of text found on a file using parallel arrays. The language to translate is pig Latin. I created a text file to use as a pig latin to English dictionary. I didn't want to use any two dimension arrays; I want to keep the arrays in one dimension.
Basically I want to read a text file written in PigLatin and using the dictionary I created I want to output the translation to English on the command line.
My pseudo-code idea is:
Open the dictionary text file.
Ask the user for the name of the text file written in PigLatin that he/she wants to translate to English
Searching each word on the user's text file and comparing to the Dictionary to then translate the word accordingly. Keep on going until there are no more words to translate.
Show the translated words on the command line screen.
I was thinking on using a parallel arrays, one containing the english translated words and another one containing the pig latin words.
I would like to know how can I manipulate the strings using arrays in C++?
Thank you.
If files will be always translated in one direction (e.g. PigLatin -> English) then it would be easier and more efficient to use std::map to map one string to another:
std::map<std::string, std::string> dictionary;
dictionary["ashtray"] = "trash";
dictionary["underplay"] = "plunder";
And get translated word, just use dictionary[] to lookup (e.g. std::cout << dictionary["upidstay"] << std::endl;)
Pig latin can be translated on the fly.
Just split the words before the first vowel of each word and you won't need a dictionary file. Then concatenate the second part with the first part, delimited with a '-', and add "ay" at the end.
Unless you want to use a dictionary file?
Declaring an array of strings is easy, the same as declaring an array of anything else.
const int MaxWords = 100;
std::string piglatin[MaxWords];
That's an array of 100 string objects, and the array is named piglatin. The strings start out empty. You can fill the array like this:
int numWords = 0;
std::ifstream input("piglatin.txt");
std::string line;
while (std::getline(input, line) && numWords < MaxWords) {
piglatin[numWords] = line;
++numWords;
}
if (numWords == MaxWords) {
std::cerr << "Too many words" << std::endl;
}
I strongly recommend you not use an array. Use a container object, such as std::vector or std::deque, instead. That way, you can load the contents of the files without knowing in advance how big the files are. With the example declaration above, you need to make sure you don't have more than 100 entries in your file, and if there are fewer than 100, then you need to keep track of how many entries in your array are valid.
std::vector<std::string> piglatin;
std::ifstream input("piglatin.txt");
std::string line;
while (std::getline(input, line)) {
piglatin.push_back(line);
}