Cutting a string into pieces - c++

How can I extract pieces from this string?
I have a file that contains:
0065445 APPLE$456
089464 MANGO$489
0012389 GUAVA$744
What I want to do is input the file line by line, then cut the string into some pieces.
0065455 Will go in a struct a[0].num
APPLE will go in struct a[0].name
456 will go in struct a[0].dollar
And similarly for other lines.
Everything is working fine, but it's not successfully getting the dollar part into its variable.
Here's the code:
#include<cstdlib>
#include<iostream>
using namespace std ;
int main(){
FILE *fp;
fp = fopen("input.txt","r");
char str[80] ;
struct abc{
int num;
char name[20];
int dollar;
};
int i = 0;
while(fgets(str,79,fp)!=NULL){
struct abc a[i] ;
sscanf(str,"%d %[^$]s$%d\n",&a[i].num,a[i].name,&a[i].dollar);
cout <<i+1 <<") Number : "<<a[i].num<<" Name : "<< a[i].name <<" Dollar : "<< a[i].dollar << endl ;
i++;
}
return 0 ;
}
/* These didn't work too.
sscanf(str,"%d %[^$]s %d\n",&a[i].num,a[i].name,&a[i].dollar);
sscanf(str,"%d %[^$]s%d\n",&a[i].num,a[i].name,&a[i].dollar);
sscanf(str,"%d %s$%d\n",&a[i].num,a[i].name,&a[i].dollar);
*/
There's 1 more problem: the first part of string is an int that starts with 0, but the zero is not being accepted in the int. How to do it?
This is working as I want now but still after parasing the string into an int I am not getting the zeroes:
#include<cstdlib>
#include<iostream>
#include<cstring>
using namespace std ;
int main(){
FILE *fp;
fp = fopen("input.txt","r");
char str[80] ;
char temp[80] ;
struct abc{
int num;
char name[20];
int dollar;
};
int i = 0;
int j = 0 ;
while(fgets(str,79,fp)!=NULL){
i = 0;
j = 0 ;
struct abc a[i] ;
char* ptr = 0; // this is used as a helper variable to strtok
ptr = strtok(str, " $\n"); // we specify the delimiters here
while (ptr != NULL)
{
if (j == 0){
strcpy(temp, ptr);
a[i].num = atoi(temp);
}
if (j == 1)
strcpy(a[i].name, ptr);
if (j == 2){
strcpy(temp, ptr);
a[i].dollar = atoi(temp);
}
ptr = strtok(NULL, " $\n");
j++;
}
cout <<i+1 <<") Number : "<<a[i].num<<" Name : "<< a[i].name <<" Dollar : "<< a[i].dollar << endl ;
i++;
}
return 0 ;
}
/* These didn't work either.
sscanf(str,"%d %[^$]s %d\n",&a[i].num,a[i].name,&a[i].dollar);
sscanf(str,"%d %[^$]s%d\n",&a[i].num,a[i].name,&a[i].dollar);
sscanf(str,"%d %s$%d\n",&a[i].num,a[i].name,&a[i].dollar);
*/

Based on the C++ tag, I'd do things a little differently. First I'd overload the stream extractor operator for your abc type:
std::istream &operator>>(std::istream &is, abc &a) {
is >> a.num;
std::getline(is, a.name, '$');
return is >> a.dollar;
}
Then you can use that to read in a file of records, such as:
abc temp;
std::vector<abc> a;
std::ifstream in("input.txt");
while (in >> temp)
a.push_back(temp);
Or, you can use an istream_iterator to initialize a vector directly from the stream:
std::vector<abc> a((std::istream_iterator<abc>(in)),
std::istream_iterator<abc>());
The easiest way to keep the leading zeros on the first number is probably to change it from an int to a std::string.

Use strtok:
Here is a simple code (C only) that prints your strings separately (I recommended a similar solution in another post).
#include <stdio.h>
#include <string.h> // for strcpy and strtok
#include <stdlib.h> // for atoi
int main()
{
char input [25] = "0065445 APPLE$4056"; // input string
// storage for the separate parts of the string
char line[10];
char fruit[10];
char number[10];
char* ptr = 0; // this is used as a helper variable to strtok
ptr = strtok(input, " $\n"); // we specify the delimiters here
int i = 0;
// I'm using i here as a control variable so that during each iteration different part
// of the string is saved
while (ptr != NULL)
{
if (i == 0)
strcpy(line, ptr);
if (i == 1)
strcpy(fruit, ptr);
if (i == 2)
strcpy(number, ptr);
ptr = strtok(NULL, " $\n");
i++;
}
printf("%s %s %s\n", line, fruit, number);
return 0;
}
Some sample output:
$ ./a.out
0065445 APPLE 4056
Is this what you need?

the 0's will not show up when you print the integer a[i].num.
You could make a[i].num a string (char[]) or an integer array. to make the 0's show up. you can parse it as an integer (via atoi(str)), if you need it to be used otherwsie.

#include <iostream>
#include <fstream>
#include <sstream>
struct abc{ int num; std::string name; int dollar; };
int main(int argc, char* argv[]) {
std::ifstream file("input");
abc st1;
std::string l;
while (file >> st1.num >> l) {
if (size_t p = l.find_first_of('$')) {
st1.name = l.substr(0, p);
std::istringstream(l.substr(p+1)) >> st1.dollar;
std::cout << st1.num << " : "
<< st1.name << " : " << st1.dollar << std::endl;
}
}
return 0;
}

Related

extracting digits from input string c++

I'm trying to do parsing to some input string reactions read from file at formula :2W+B=8A+10Z, I'm not interested in characters i need only to split and extract the integer values to put them in a vector i.e vector associated with the reaction here is :[2 1 8 10]
i thought about many things: std::strtok(),isdigital(),find_first_of() but they all didn't work for integer values ... can any body help ??
here my try:
int main()
{
std::string input;
std::getline(std::cin, input);
std::stringstream stream(input);
while(1) {
int n;
stream >> n;
char * pch;
pch = strtok (input," ");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.");
}
}
}
This will do what you want in this particular case. However, i suggest that you look into regex to parse your equation better. You may want to consider all possible cases for your input. This includes \,-,* and other operators that you may want to add in your equation. Also, I'm assuming variables in your equation has only one character.
int main()
{
string input;
getline(std::cin, input);
stringstream stream(input);
char tmp[256];
const char *in = input.c_str();
char str[256];
strcpy(str,in);
int x;
tmp[0]='\0';
char c;
vector<int> vec;
//Scan for the digit
//if it is, store the rest of the string back to str
//if it isn't, store the part of the string before a digit to tmp
while (sscanf(str,"%d%s",&x,str) || sscanf(str,"%[^0123456789]%s",tmp,str) > 1)
{
//check if tmp has the form [variable name]+[a string]
//a string can include another variable name and an operator, = in this case
while(sscanf(tmp,"%c+%[^0123456789]",&c,tmp) > 1)
vec.push_back(1);
if (tmp[0]=='\0')
vec.push_back(x);
tmp[0]='\0';
}
//just in case there're more special cases
while(sscanf(str,"%c+%[^0123456789]",&c,str) > 1)
vec.push_back(1);
for(int i = 0; i < vec.size(); i++)
cout << vec[i] << endl;
}
Output:
2
1
8
10
See comments for explanation.
EDIT
Be careful when you have a special case 2W+B=8A+10Z+C+D. Notice the last C D should both have coefficients 1. This could happen in the middle of the equation too.
Here is another solution:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string equ;
vector<int> digits;
cout << "enter your equation: \n";
cin >> equ;
for (auto i : equ)
{
if (isdigit(i))
{
digits.push_back(stoi(string{i}));
}
}
for (auto& i : digits)
{
cout << i << endl;
}
system("pause");
return 0;
}
You could simply do something like this, for comments see code
#include <iostream>
#include <string>
#include <vector>
std::vector<int> Split(std::string str)
{
std::vector<int> result; // will contain the different ints
// set pointer to first character in the string
char const* pch = str.c_str();
std::string digit; // buffer to keep digits if more than one
int sign = 1; // each number has a sign -1 or 1
for (; *pch; ++pch)
{
if (std::isdigit(*pch)) // if a digit, put in temp buffer
{
digit += *pch;
}
else if (std::isalpha(*pch)) // if not a digit evaluate the ones we have
{
if (digit.empty()) // none so assume 1 before letter e.g. W+2B
{
result.push_back(1*sign);
}
else
{
result.push_back(stoi(digit)*sign);
digit = "";
}
}
else // determine sign of number
{
digit = "";
if (*pch == '+')
{
sign = 1;
}
else if (*pch == '-')
{
sign = -1;
}
}
}
return result;
}
int main()
{
using namespace std;
string expr{"-2W+B=-8A+10Z"};
auto digits = Split(expr);
for (auto& digit : digits)
{
cout << digit << endl;
}
return 0;
}

Returning string from a function causing formatting issues

It's supposed to look like this: http://i.imgur.com/gko501E.png
Instead it looks like this: http://i.imgur.com/ISwqyD8.png
When I take the code out of the function and use it in the main class it works properly. However once I put it in this function the formatting problems occur, it also isn't filtering like it's supposed to. This program is supposed to take user input, store it in a string, remove all non-alphabetical characters, capitalize the vowels, and then space it out based on user defined variables given in the command line. It's also supposed to accept files as input in the command line, such as: 'program 5 8 < file'.
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <cstdlib>
#include <fstream>
#include <sstream>
using namespace std;
//make vowels uppercase
string filter(string input)
{
size_t found = input.find_first_of("aeiou");
while (found != string::npos)
{
if (islower(input[found]))
{
input[found] = toupper(input[found]);
found = input.find_first_of("aeiou", found + 1);
}
}
//Make consonants lowercase
size_t foundLower = input.find_first_of("BCDFGHJKLMNPQRSTVWXYZ");
while (foundLower != string::npos)
{
if (isupper(input[foundLower]))
{
input[foundLower] = tolower(input[foundLower]);
foundLower = input.find_first_of("BCDFGHJKLMNPQRSTVWXYZ", foundLower + 1);
}
}
//remove punctuation
for (int i = 0, len = input.size(); i < len; i++)
{
if (!isalnum(input[i]))
{
input.erase(i--, 1);
len = input.size();
}
}
return input;
}
int main(int argc, char* argv[])
{
int wordSize;
int wordSizeCounter;
int wordCounter = 0;
int rowSize;
//char letter;
wordSize = atoi(argv[1]);
rowSize = atoi(argv[2]);
ifstream inFile;
inFile.open(argv[3]);//open the input file
stringstream strStream;
strStream << inFile.rdbuf();//read the file
string test = strStream.str();//str holds the content of the file
if (!inFile) test = cin.get() ; // Read first character
//Begin filter for files
while (!test.empty())
{
filter(test);
if (test.length() < wordSize) //make sure we don't go out-of-bounds
{
wordSize = test.length();
}
cout << test.substr(0, wordSize);
cout << " ";
if (test.length() >= wordSize) //again, make sure we don't go out-of-bounds
{
test = test.substr(wordSize);
}
else
{
test = " ";
}
wordCounter++;
if (wordCounter == rowSize)
{
cout << std::endl;
wordCounter = 0;
}
if(test.empty())
{
test = cin.get();
}
}
cout << endl;
return 0;
}

Write a string to file not equal to string that read from it

Phase 1
example 1: I have string text = "01100001" then I want write to file "a"
example 2: I have string text = "0110000101100010" So I want write to file "ab"
NOTE:I solved phase 1 and result of writing is true.
Phase 2
for example 1:
I want read the file and put it to temp.
So temp = "a" and i convert it to "01100001"
for example 2:
I want read the file and put it to temp.
So temp = "ab" and i convert it to "0110000101100010"
Question
in my code i have below input
string text ="00000110101011100010001011111110011011110101100101110101101111010111111110101011"
"00111011000011100011100000100010111110111110111001100001110001110000101001111010"
"00000101";
I did "phase 1" and I opened the file in a hex editor the writing is true.
But after doing "phase 2" temp != text. Why?
My code
#include <iostream>
#include <sstream>
#include <vector>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
class bitChar{
public:
unsigned char* c;
int shift_count;
string BITS;
bitChar()
{
shift_count = 0;
c = (unsigned char*)calloc(1, sizeof(char));
}
string readByBits(ifstream& inf)
{
string s ="";
while (inf)
{
string strInput;
getline(inf, strInput );
for (int i =0 ; i < strInput.size() ; i++)
{
s += getBits(strInput[i]);
}
}
return s;
}
void setBITS(string X)
{
BITS = X;
}
int insertBits(ofstream& outf)
{
int total = 0 ;
while(BITS.length())
{
if(BITS[0] == '1')
*c |= 1;
*c <<= 1;
++shift_count;
++total;
BITS.erase(0, 1);
if(shift_count == 7 )
{
if(BITS.size()>0)
{
if(BITS[0] == '1')
*c |= 1;
++total;
BITS.erase(0, 1);
}
writeBits(outf);
shift_count = 0;
free(c);
c = (unsigned char*)calloc(1, sizeof(char));
}
}
if(shift_count > 0)
{
*c <<= (7 - shift_count);
writeBits(outf);
free(c);
c = (unsigned char*)calloc(1, sizeof(char));
}
outf.close();
return total;
}
string getBits(unsigned char X)
{
stringstream itoa;
for(unsigned s = 7; s > 0 ; s--)
{
itoa << ((X >> s) & 1);
}
itoa << (X&1) ;
return itoa.str();
}
void writeBits(ofstream& outf)
{
outf << *c;
}
~bitChar()
{
if(c)
free(c);
}
};
int main()
{
ofstream outf("ssSample.dat",ios::binary);
string text ="00000110101011100010001011111110011011110101100101110101101111010111111110101011"
"00111011000011100011100000100010111110111110111001100001110001110000101001111010"
"00000101";
cout<< text<<endl;
//write to file
bitChar bchar;
bchar.setBITS(text);
bchar.insertBits(outf);
outf.close();
ifstream inf("ssSample.dat" ,ios::binary);
//READ FROM FILE
string temp=bchar.readByBits(inf);
cout << endl;
cout << temp << endl;
return 0;
}
You have a LF Line Feed character. This is the character that is getting omitted.
0000 1010
This may be unrelated, but Windows requires a CR and LF for a new line. This code may act differently in Windows vs. Unix.
Read one byte at a time.
string readByBits(ifstream& inf)
{
string s ="";
char buffer[1];
while (inf.read (buffer, 1))
{
// string strInput;
//getline(inf, strInput );
//for (int i =0 ; i < strInput.size() ; i++)
//{
s += getBits(*buffer);
//}
}
return s;
}
Program output:
000001101010111000100010111111100110111101011001011101011011110101111111101010110011101100001110001110000010001011111011111011100110000111000111000010100111101000000101
000001101010111000100010111111100110111101011001011101011011110101111111101010110011101100001110001110000010001011111011111011100110000111000111000010100111101000000101
One problem with your approach is that your text must be a multiple of 8 bits to work. Otherwise, even if everything is correct, that last character will be read from the file and converted to 8 binary digits in the string adding trailing zeros.
Two problems I quickly identified (but I assume there are more)
Your input is not a multiple of 8-bits
By using getLine you're reading until you meet a delimiting character and thus spoiling your result since you're not dealing with a text-based file

C++ Hex string to byte array

First off, I've Googled this question over the past few days but everything I find doesn't work. I don't receive runtime errors but when I type in the same key (in the form of a hex string) that the program generates to encrypt, decryption fails (but using the generated key throughout the program works fine). I'm trying to enter a hex string (format: 00:00:00...) and turn it into a 32-byte byte array. The input comes from getpass(). I've done this before in Java and C# but I'm new to C++ and everything seems much more complicated. Any help would be greatly appreciated :) Also I'm programming this on a linux platform so I'd like to avoid Windows-only functions.
Here is an example of what I've tried:
char *pass = getpass("Key: ");
std::stringstream converter;
std::istringstream ss( pass );
std::vector<byte> bytes;
std::string word;
while( ss >> word )
{
byte temp;
converter << std::hex << word;
converter >> temp;
bytes.push_back( temp );
}
byte* keyBytes = &bytes[0];
If your input has format: AA:BB:CC,
you could write something like this:
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cstdint>
struct hex_to_byte
{
static uint8_t low(const char& value)
{
if(value <= '9' && '0' <= value)
{
return static_cast<uint8_t>(value - '0');
}
else // ('A' <= value && value <= 'F')
{
return static_cast<uint8_t>(10 + (value - 'A'));
}
}
static uint8_t high(const char& value)
{
return (low(value) << 4);
}
};
template <typename InputIterator>
std::string from_hex(InputIterator first, InputIterator last)
{
std::ostringstream oss;
while(first != last)
{
char highValue = *first++;
if(highValue == ':')
continue;
char lowValue = *first++;
char ch = (hex_to_byte::high(highValue) | hex_to_byte::low(lowValue));
oss << ch;
}
return oss.str();
}
int main()
{
std::string pass = "AB:DC:EF";
std::string bin_str = from_hex(std::begin(pass), std::end(pass));
std::vector<std::uint8_t> v(std::begin(bin_str), std::end(bin_str)); // bytes: [171, 220, 239]
return 0;
}
How about this?
Read it as a word and operate on it after?
You can do any size checking format checking in convert().
#include <iostream>
#include <string>
#include <vector>
char convert(char c)
{
using namespace std;
// do whatever decryption stuff you want here
return c;
}
void test()
{
using namespace std;
string word;
cin >> word;
vector<char> password;
for (int i = 0; i < word.length(); i++)
{
password.push_back(convert(word[i]));
}
for (int i = 0; i < password.size(); i++)
{
cout << password[i];
}
cout << "";
}
int main()
{
using namespace std;
char wait = ' ';
test();
cin >> wait;
}
Are there specific reasons for not using cin here?

Printing input string words in reverse order

Using if and while/do-while, my job is to print following user's inputs (string value) in reverse order.
For example:
input string value : "You are American"
output in reverse order : "American are You"
Is there any way to do this?
I have tried
string a;
cout << "enter a string: ";
getline(cin, a);
a = string ( a.rbegin(), a.rend() );
cout << a << endl;
return 0;
...but this would reverse the order of the words and spelling while spelling is not what I'm going for.
I also should be adding in if and while statements but do not have a clue how.
The algorithm is:
Reverse the whole string
Reverse the individual words
#include<iostream>
#include<algorithm>
using namespace std;
string reverseWords(string a)
{
reverse(a.begin(), a.end());
int s = 0;
int i = 0;
while(i < a.length())
{
if(a[i] == ' ')
{
reverse(a.begin() + s, a.begin() + i);
s = i + 1;
}
i++;
}
if(a[a.length() - 1] != ' ')
{
reverse(a.begin() + s, a.end());
}
return a;
}
Here is a C-based approach that will compile with a C++ compiler, which uses the stack to minimize creation of char * strings. With minimal work, this can be adapted to use C++ classes, as well as trivially replacing the various for loops with a do-while or while block.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LENGTH 1000
#define MAX_WORD_LENGTH 80
void rev(char *str)
{
size_t str_length = strlen(str);
int str_idx;
char word_buffer[MAX_WORD_LENGTH] = {0};
int word_buffer_idx = 0;
for (str_idx = str_length - 1; str_idx >= 0; str_idx--)
word_buffer[word_buffer_idx++] = str[str_idx];
memcpy(str, word_buffer, word_buffer_idx);
str[word_buffer_idx] = '\0';
}
int main(int argc, char **argv)
{
char *line = NULL;
size_t line_length;
int line_idx;
char word_buffer[MAX_WORD_LENGTH] = {0};
int word_buffer_idx;
/* set up line buffer - we cast the result of malloc() because we're using C++ */
line = (char *) malloc (MAX_LINE_LENGTH + 1);
if (!line) {
fprintf(stderr, "ERROR: Could not allocate space for line buffer!\n");
return EXIT_FAILURE;
}
/* read in a line of characters from standard input */
getline(&line, &line_length, stdin);
/* replace newline with NUL character to correctly terminate 'line' */
for (line_idx = 0; line_idx < (int) line_length; line_idx++) {
if (line[line_idx] == '\n') {
line[line_idx] = '\0';
line_length = line_idx;
break;
}
}
/* put the reverse of a word into a buffer, else print the reverse of the word buffer if we encounter a space */
for (line_idx = line_length - 1, word_buffer_idx = 0; line_idx >= -1; line_idx--) {
if (line_idx == -1)
word_buffer[word_buffer_idx] = '\0', rev(word_buffer), fprintf(stdout, "%s\n", word_buffer);
else if (line[line_idx] == ' ')
word_buffer[word_buffer_idx] = '\0', rev(word_buffer), fprintf(stdout, "%s ", word_buffer), word_buffer_idx = 0;
else
word_buffer[word_buffer_idx++] = line[line_idx];
}
/* cleanup memory, to avoid leaks */
free(line);
return EXIT_SUCCESS;
}
To compile with a C++ compiler, and then use:
$ g++ -Wall test.c -o test
$ ./test
foo bar baz
baz bar foo
This example unpacks the input string one word at a time,
and builds an output string by concatenating in reverse order.
`
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
string inp_str("I am British");
string out_str("");
string word_str;
istringstream iss( inp_str );
while (iss >> word_str) {
out_str = word_str + " " + out_str;
} // while (my_iss >> my_word)
cout << out_str << endl;
return 0;
} // main
`
This uses exactly one each of if and while.
#include <string>
#include <iostream>
#include <sstream>
void backwards(std::istream& in, std::ostream& out)
{
std::string word;
if (in >> word) // Read the frontmost word
{
backwards(in, out); // Output the rest of the input backwards...
out << word << " "; // ... and output the frontmost word at the back
}
}
int main()
{
std::string line;
while (getline(std::cin, line))
{
std::istringstream input(line);
backwards(input, std::cout);
std::cout << std::endl;
}
}
You might try this solution in getting a vector of string's using the ' ' (single space) character as a delimiter.
The next step would be to iterate over this vector backwards to generate the reverse string.
Here's what it might look like (split is the string splitting function from that post):
Edit 2: If you don't like vectors for whatever reason, you can use arrays (note that pointers can act as arrays). This example allocates a fixed size array on the heap, you may want to change this to say, double the size when the current word amount has reached a certain value.
Solution using an array instead of a vector:
#include <iostream>
#include <string>
using namespace std;
int getWords(string input, string ** output)
{
*output = new string[256]; // Assumes there will be a max of 256 words (can make this more dynamic if you want)
string currentWord;
int currentWordIndex = 0;
for(int i = 0; i <= input.length(); i++)
{
if(i == input.length() || input[i] == ' ') // We've found a space, so we've reached a new word
{
if(currentWord.length() > 0)
{
(*output)[currentWordIndex] = currentWord;
currentWordIndex++;
}
currentWord.clear();
}
else
{
currentWord.push_back(input[i]); // Add this character to the current word
}
}
return currentWordIndex; // returns the number of words
}
int main ()
{
std::string original, reverse;
std::getline(std::cin, original); // Get the input string
string * arrWords;
int size = getWords(original, &arrWords); // pass in the address of the arrWords array
int index = size - 1;
while(index >= 0)
{
reverse.append(arrWords[index]);
reverse.append(" ");
index--;
}
std::cout << reverse << std::endl;
return 0;
}
Edit: Added includes, main function, while loop format
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
// From the post
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems)
{
std::stringstream ss(s);
std::string item;
while(std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
return split(s, delim, elems);
}
int main ()
{
std::string original, reverse;
std::cout << "Input a string: " << std::endl;
std::getline(std::cin, original); // Get the input string
std::vector<std::string> words = split(original, ' ');
std::vector<std::string>::reverse_iterator rit = words.rbegin();
while(rit != words.rend())
{
reverse.append(*rit);
reverse.append(" "); // add a space
rit++;
}
std::cout << reverse << std::endl;
return 0;
}
This code here uses string libraries to detect the blanks in the input stream and rewrite the output sentence accordingly
The algorithm is
1. Get the input stream using getline function to capture the spacecs. Initialize pos1 to zero.
2. Look for the first space in the input stream
3. If no space is found, the input stream is the output
4. Else, get the position of the first blank after pos1, i.e. pos2.
5. Save the sub-string bewteen pos1 and pos2 at the beginning of the output sentence; newSentence.
6. Pos1 is now at the first char after the blank.
7. Repeat 4, 5 and 6 untill no spaces left.
8. Add the last sub-string to at the beginning of the newSentence. –
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string sentence;
string newSentence;
string::size_type pos1;
string::size_type pos2;
string::size_type len;
cout << "This sentence rewrites a sentence backward word by word\n"
"Hello world => world Hello"<<endl;
getline(cin, sentence);
pos1 = 0;
len = sentence.length();
pos2 = sentence.find(' ',pos1);
while (pos2 != string::npos)
{
newSentence = sentence.substr(pos1, pos2-pos1+1) + newSentence;
pos1 = pos2 + 1;
pos2 = sentence.find(' ',pos1);
}
newSentence = sentence.substr(pos1, len-pos1+1) + " " + newSentence;
cout << endl << newSentence <<endl;
return 0;
}