This question has been done to death in SO:. Here is my version using STL functions of the tradition algorithm of reversing the string and then reversing the words. is there a more elegant soln without using loops?
std::string something;
std::getline(std::cin, something);
std::reverse(something.begin(), something.end());
for (size_t i = 0, size_t nextPos = something.find_first_of(' ', i);
nextPos != std::string::npos; i = nextPos + 1,
nextPos = something.find_first_of(' ', i)) {
std::string::iterator startIter = something.begin() + i;
std::string::iterator endIter = something.begin() + nextPos;
std::reverse(startIter, endIter);
}
Assume the input is perfect no space before and after sentence and exactly single space between words. Is there an stl solution that requires no loop?
Best,
Subramanian
Here's a loop-free way using iterators and a closure:
#include <iterator>
#include <algorithm>
#include <sstream>
#include <string>
std::istringstream iss(something);
std::string sentence;
std::for_each(std::istream_iterator<std::string>(iss),
std::istream_iterator<std::string>(),
[&sentence](std::string const & s) { sentence.insert(0, s + ' '); }
);
Update: Here is an in-place algorithm with one single loop:
#include <string>
#include <algorithm>
void reverse(std::string & s)
{
for (std::size_t pos, done = 0;
(pos = s.find(' ')) != s.npos && ++pos + done <= s.size();
done += pos)
{
std::rotate(s.begin(), s.begin() + pos, s.end() - done);
}
}
Example:
#include <iostream>
int main()
{
for (std::string line; std::getline(std::cin, line); )
{
reverse(line);
std::cout << '"' << line << '"' << std::endl;
}
}
Test run:
$ echo "hello world how are you " | ./prog
"you are how world hello "
Related
I was trying to make a program write 8 words to a line after a user enter their sentence.Its only printing words that have been typed in and i don't have a clue how to make it type 8 words to a line.
#include <iostream>
#include <vector>
#include <string>
#include <cctype>
using namespace std;
vector<string> sentence;
string sente = "";
void print(string, string);
template<typename T>
void print(vector<T>& v, string)
{
cout << "Enter your sentence " << endl;
getline(cin, sente);
sentence.push_back(sente);
for (auto const elem: sentence)
{
cout << elem;
}
}
int main()
{
print(sentence,sente);
}
Using global variables is generally not a good practice.
Also you don't need a extra vector for your use case.
Take a look at the following code, where you can smartly make use of istringstream for your use case:
#include <iostream>
#include <string>
#include <sstream>
void print()
{
std::string sente;
std::cout << "Enter your sentence " << std::endl;
getline(std::cin, sente);
// Used to split string around spaces.
std::istringstream ss(sente);
int wordCountPerLine = 0;
int requiredWordsPerLine = 8;
// Traverse through all words
do {
// Read a word
std::string word;
ss >> word;
// Print the read word
std::cout << word << " ";
wordCountPerLine++;
if(wordCountPerLine % requiredWordsPerLine == 0){
std::cout<<std::endl;
wordCountPerLine = 0;
}
// While there is more to read
} while (ss);
}
int main()
{
print();
}
Feel free to ask any doubts.
I need to write a table from a file in a map > m.
I have 3 strings (state, next_states, outputs)
and i want to write them like this (I know it's not correct)
for (i=0; i < 5; i++)
{
//here I have a code, the 3 strings change for every line
for(j=0; j<m.size(); j++)
{
m[i][j] = "state" + "next_states" + "outputs";
}
}
I thought maybe with iterator it would be better but i don't know how to do it.
Here is how you can iterate through your map:
#include <iostream>
#include <map>
#include <vector>
#include <string>
int main()
{
std::map <std::string, std::vector<std::string>> m =
{
{"1", {"a", "b"}},
{"2", {"c", "d", "e"}},
};
for (auto& element : m)
{
std::cout << element.first << " : ";
for (auto& str : element.second)
{
std::cout << str << "; ";
}
std::cout << std::endl;
}
}
In my source file when I define my object s, Visual Studios says Identifier "stack" is undefined. I'm pretty sure I've separated the headers correctly but I don't know why I'm getting this error. Also side note when I put everything together in one source file and compile it, it just exits immediately without any reason. Thanks for the help in advance.
This is the source file
// pa3.cpp : Defines the entry point for the console application.
//
#include "stack.h"
#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
//#include <ctype.h>
using namespace std;
int main()
{
//int count;
stack s; //assign s object to stack
string input;
cout << "Please enter the name of the input file: \n";
//cin >> input;
getline(cin, input);
ifstream file(input);
string readline;
//ifstream file(input);
while (getline(file, readline)) //take first line of file and assign to readline
{
s.push(readline); //send it off to push
s.retrieveUPPER();
//file.close();
system("pause");
}
return 0;
}
This is the stack.h file
//#pragma once
#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
//#include <ctype.h>
using namespace std;
class stack
{
public:
int count;
void push(string);
//void pop();
void check(string);
void retrieveUPPER();
private:
static string firstline[1];
static string diskeywords[3];
static char upperword[100];
static char lowerword[100];
static char operatorsarr[100];
static char delimitersarr[100];
};
This is the stack.cpp
#include "stack.h"
#include "stdafx.h"
#include <iostream>
string stack::firstline[1] = { 0 };
string stack::diskeywords[3];
char stack::upperword[100];
char stack::lowerword[100];
char stack::operatorsarr[100];
char stack::delimitersarr[100];
void stack::retrieveUPPER()
{
for (int i = 0; i < 100; i++)
{
cout << upperword[i] << "\n";
}
}
void stack::push(string readline)
{
firstline[0] = readline;
count++;
check(readline);
}
void stack::check(string readline)
{
int length;
char letter;
int leftperenthe = 0;
int rightperenthe = 0;
//int capital;
//int wordFOR;
//int wordBEGIN;
//char keywords[3][8] = { "FOR", "BEGIN", "END" };
char operators[] = "+-=*/;";
char delimiters[] = { ',',';' };
length = readline.length();
for (int i = 0; i < length; i++)
{
for (int j = 0; j < 5; j++)
{
letter = readline[i];
if (isupper(letter)) //if capital letter
{
upperword[i] = letter;
}
else if (islower(letter)) //if lowercase letter
{
lowerword[i] = letter;
}
else if (letter == operators[j]) //if encounters a operator
{
operatorsarr[i] = letter;
}
else if (letter == delimiters[j]) //if encounters a delimiter
{
delimitersarr[i] = letter;
}
else if (letter = ' ') //if encounters a space
{
lowerword[i] = ' ';
operatorsarr[i] = ' ';
delimitersarr[i] = ' ';
}
else if (letter = '(') //if left perenthesis
{
leftperenthe++;
}
else if (letter = ')') //if right perenthesis
{
rightperenthe++;
}
}
}
}
I also had a similar situation:
#include<iostream>
#include<stack.h>
#include<vector>
using namespace std;
int main();
std::vector<int>stickPan (std::vector<int>arr)
{
stack<int>s;
...
}
I used VScode, used mingw-w64, and added paths for * .h files to .json files, but it didn't work.
Errors are reported:
identifier "stack" is undefined.
type name is not allowed.
identifier "s" is undefined
I am trying to tokenize a database dump separated by commas. I only need to read the first word, which will tell me if this is the line I need and then tokenize the line and save each separated string in a vector.
I have had trouble keeping all of the datatypes in order. I use a method of getline:
string line;
vector<string> tokens;
// Iterate through each line of the file
while( getline( file, line ) )
{
// Here is where i want to tokenize. strtok however uses a character array and not a string.
}
The thing is, I only want to continue reading and tokenize a line if the first word is what I am after. Here is a sample of a line from the file:
example,1,200,200,220,10,550,550,550,0,100,0,-84,255
So, if I am after the string example, it goes ahead and tokenizes the rest of the line for my use and then stops reading from the file.
Should I be using strtok, stringstream or something else?
Thank you!
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
void do(ifstream& file) {
string line;
string prefix = "example,";
// Get all lines from the file
while (getline(file,line).good()) {
// Compare the beginning for your prefix
if (line.compare(0, prefix.size(), prefix) == 0) {
// Homemade tokenization
vector<string> tokens;
int oldpos = 0;
int pos;
while ((pos = line.find(',', oldpos)) != string::npos) {
tokens.push_back(line.substr(oldpos, pos-oldpos));
oldpos = pos + 1;
}
tokens.push_back(line.substr(oldpos)); // don't forget the last bit
// And here you are!
}
}
}
How do I tokenize a string in C++?
http://www.daniweb.com/software-development/cpp/threads/27905
Hope this helps, though I am not proficient C/C++ programmer. For the record it would be nice if you could specify in the tags or in post language you are using.
Tokenizer.h
#ifndef TOKENIZER_H
#define TOKENIZER_H
#include <string>
#include <vector>
#include <sstream>
class Tokenizer
{
public:
Tokenizer();
~Tokenizer();
void Tokenize(std::string& str, std::vector<std::string>& tokens);
};
#endif /* TOKENIZER_H */
Tokenizer.cpp
#include "Tokenizer.h"
using namespace std;
string seps(string& s) {
if (!s.size()) return "";
stringstream ss;
ss << s[0];
for (int i = 1; i < s.size(); i++)
ss << '|' << s[i];
return ss.str();
}
void tok(string& str, vector<string>& tokens, const string& delimiters = ",")
{
seps(str);
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
tokens.push_back(str.substr(lastPos, pos - lastPos));
lastPos = str.find_first_not_of(delimiters, pos);
pos = str.find_first_of(delimiters, lastPos);
}
}
Tokenizer::Tokenizer()
{
}
void Tokenizer::Tokenize(string& str, vector<string>& tokens)
{
tok(seps(str), tokens);
}
Tokenizer::~Tokenizer()
{
}
To tokenize a string
#include "Tokenizer.h"
#include <string>
#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
// Required variables for later below
vector<string> t;
string s = "This is one string,This is another,And this is another one aswell.";
// What you need to include:
Tokenizer tokenizer;
tokenizer.Tokenize(s, t); // s = a string to tokenize, t = vector to store tokens
// Below is just to show the tokens in the vector<string> (c++11+)
for (auto c : t)
cout << c << endl;
system("pause");
return 0;
}
is there any STL algorithm or a standard way of finding how many occurences of particular substring are there in a string? For example in string:
'How do you do at ou'
the string "ou" appears twice. I tried some STL algorithms with and without predicates but what I found is that those algorithms from STL want to compare components of string which in my case is char but cannot? compare substrings.
I come up with something like this:
str - string
obj - substring we're looking for
std::string::size_type count_subs(const std::string& str, const std::string& obj)
{
std::string::const_iterator beg = str.begin();
std::string::const_iterator end = str.end();
std::string::size_type count = 0;
while ((beg + (obj.size() - 1)) != end)
{
std::string tmp(beg, beg + obj.size());
if (tmp == obj)
{
++count;
}
++beg;
}
return count;
}
thank you.
#include <string>
#include <iostream>
int Count( const std::string & str,
const std::string & obj ) {
int n = 0;
std::string ::size_type pos = 0;
while( (pos = obj.find( str, pos ))
!= std::string::npos ) {
n++;
pos += str.size();
}
return n;
}
int main() {
std::string s = "How do you do at ou";
int n = Count( "ou", s );
std::cout << n << std::endl;
}