Reputation: 2036
#include <iostream>
#include <cstring>
using namespace std;
void reverse(char* sentence)
{
int index = strlen(sentence) - 1;
char last = '\0';
int hold = 0;
while ( index != 0){
while (sentence[index] != ' ')
index--;
hold = index; //keeps the index of whitespace
while (sentence[index] != last){
cout << sentence[index]; //printing till it either hits end character or whitespace.
index++;
}
last = sentence[hold]; //Keeps the whitespace
index = hold; //
}
}
int main()
{
char* sentence = new char[256];
cin.getline(sentence, 256);
reverse(sentence);
}
I want to reverse the orders of words in a sentence and you can see my attempt above.
Sample intput and output should be like this:
Howdy Mr. Mcfly?
Mcfly? Mr. Howdy
Where i get:
Howdy Mr. Mcfly?
Mcfly?
There are many similar questions around the internet but what i want is to find error in my own code.
Upvotes: 6
Views: 23894
Reputation: 21
You can do it by istringstream class of C++
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s,st,w;
int i;
getline(cin,s);
istringstream is(s);
st="";
is>>st;
while(is>>w)
{
st=w+' '+st;
}
cout<<st<<endl;
return 0;
}
Upvotes: 0
Reputation: 1
Here I used splitting (tokenizing) sentence into words and then use that for reverse printing. Hope this help-
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
vector<string> split(char* str, char delimiter=' ')
{
vector<string> result;
do
{
char* begin =str;
while(*str != delimiter && *str)
str++;
result.push_back(string(begin, str));
}while(0 != *str++);
return result;
}
int main()
{
string str;
vector<string> tempStr;
cout<<"Enter The String: ";
getline(cin, str);
cout<<endl;
tempStr=split((char*)str.c_str());
str.clear();
cout<<"Final Reverse: \n";
for(int i=tempStr.size()-1; i>=0; i--) str+=tempStr.at(i)+" ";
//cout<<tempStr.at(i)<<" ";
cout<<str<<endl;
return 0;
}
Upvotes: 0
Reputation: 1
I would like to use stack. 1.Tokenize the string using delimiter("") 2. push the word into the stack 3. As you pops up, store that word in the new string variable.
Upvotes: 0
Reputation: 10355
You can use std::string
std::vector
and std::reverse
to make things easier:
std::string sentence = "Your sentence which contains ten words, two of them numbers";
std::stringstream stream(sentence);
std::vector<std::string> words;
for ( std::string word; stream >> word; )
{
words.push_back(word);
}
Now you have everything separated into words. You may now want to remove question marks or other punctuation, since the logic will be easier to implement while the words are still in the correct order. For reversing, do this:
std::reverse(words.begin(), word.end());
You'll need to include several headers:
#include <string> // for storing strings in a C++ way
#include <sstream> // to easily separate sentences into words
#include <vector> // to dynamically store arbitrary amounts of words
#include <algorithm> // for std::reverse
You can see this code in action with this demo on ideone.com
Upvotes: 12
Reputation: 5239
As the other answers suggest you should use std::string
which can save lot of hassles.
But just for the note,
void reverse(char* sentence)
{
int index = strlen(sentence) - 1,hold,last = '\0';
/*For the 1st iteration last is `\0` for all others it is ` `*/
while (index >= 0)
{
/*
In your original code,
This while loop(below) will continue to keep decrementing index
even below `0`,You wont exit this while loop until you encounter a ` `.
For the 1st word of the sentence you will never come out of the loop.
Hence the check, index>=0
*/
while (index>=0 && sentence[index] != ' ')
index--;
/* You can print the whitespace later*/
hold = index - 1; // This keeps track of the last character
// of preceding word
index++; //character after space
while (sentence[index] != last)
{
cout << sentence[index];
index++;
}
last = ' ';
index = hold;
/* Dont print space after 1st word*/
if(index > 0)
cout<<" ";
}
}
int main()
{
char* sentence = new char[256];
cin.getline(sentence, 256);
reverse(sentence);
delete[] sentence; // Delete the allocated memory
}
Tryin to keep it as close to your logic
Upvotes: 4
Reputation: 1717
#include <sstream>
#include <iostream>
#include <list>
int main() {
char sentence[256];
std::cin.getline(sentence, 256);
std::istringstream f(sentence );
std::string s;
std::list<std::string> strings;
while (f >> s)
{
strings.push_front(s);
}
}
at this moment strings
contains the words in reverse order
Upvotes: 1
Reputation: 393239
Correction to the earlier version, firmly tongue-in-cheek :)
Note that the program reads all of stdin, treating each individual line as a 'sentence'.
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace phx= boost::phoenix;
using namespace boost::spirit::qi;
int main()
{
auto out = std::ostream_iterator<std::string>(std::cout, " ");
boost::spirit::istream_iterator f(std::cin), l;
std::cin.unsetf(std::ios::skipws);
parse(f, l,
(
(as_string [ +~char_("\n\t ") ] % +char_("\t "))
[ phx::reverse(_1), phx::copy(_1, phx::ref(out)) ]
) % eol [ phx::ref(std::cout) << "\n" ]
);
}
Upvotes: 0
Reputation: 18870
When you say
index = hold;
You hav ean infinite loop. You're always going back to the point where you find your '\0' character I believe. What you should do is have two separate while loops. One to get you to the end of your character array, to find '\0'. And then another set of loops to return back to white space, then loop back forward printing out characters.
NOTE: I like all the answers presented better, but this is why the code you posted is failing. Here is a version of this function that works with just cstrings.
void reverse(char* sentence, const int START)
{
if(sentence[START] == '\0') return;
char last = '\0';
int hold = 0;
int index = START + 1;
while(sentence[index] != '\0' && sentence[index] != ' ') {//There are better ways to do this logic, but I wanted to remain true to your implementation as much as possible
index++;
}
reverse(sentence, index);
for(int j = START; j < index; j++) {
cout << sentence[j];
}
cout << endl;
return;
}
I prints out a few extra end lines, you can of course format the output however you like, the hard part is done.
Upvotes: 1