4
\$\begingroup\$
#include<stdafx.h>#include<stdio.h>#include<stdlib.h>#include<string>#include<iostream>using namespace std;string temp[10];void extract(char * c){    int ind = 0;    //char *temp = (char *)malloc(sizeof(char));    while(*c!= NULL)    {        if(*c!= ' ') // read all chars in a word and store in temp.        {        temp[ind]= temp[ind] + *c;        c++;        }        else if(*c== ' ') // reached end of word        {        c++;        ind++;        }    }    int length = sizeof(temp)/sizeof(temp[0]);    printf("The reversed string is");    for(int i=length;i>=0;i--)    {    cout<<temp[i];// not able to print it with printf statement    }}void main(){char *c = "seattle is good";extract(c);}

This should print the sentence in reverse order . Input is "seattle is good"Output for the above will be "good is seattle"I have 2 questions , 1. I am using string array here with size of 10. How can I make it dynamic?2. For some reason the printf("%s",temp[i]) was not giving me correct results(At the very end of extract method). I then used cout and it was fine. Any ideas why? Am I doing something silly?

Algorithm Description:

  • Take the input string as char array.
  • Extract words from the string by looking for empty space.
  • Store each word in a temp string array.temp[0] = seattletemp[1] = istemp[2] = good
  • Then loop backwards through this temp array and print contents.
sepp2k's user avatar
sepp2k
9,0522 gold badges39 silver badges51 bronze badges
askedMar 11, 2011 at 22:08
\$\endgroup\$
0

3 Answers3

12
\$\begingroup\$

In response to your specific questions:

  1. Use a vector. Using a vector you can just append to the end and it will resize itself as necessary.
  2. You can not useprintf withstrings asprintf is a C function and does not know C++'sstrings. Either way you should generally avoidprintf in C++ code.

General notes on your code:

#include<stdafx.h>#include<stdio.h>#include<stdlib.h>

The correct way to include C header files in C++ is to use#include <cheadername>, not#include <headername.h>. Further you should avoid C-functions when there are good C++ alternatives and you should generally not mix C's stdio with C++'s iostream. In this particular program I do not believe you need any of the C headers you include.


string temp[10];

I don't see any reason to have your global storage as a global variable. You should move it as a local variable inside theextract method. And as I already said, you should use avector instead of a C array.

Alsotemp is a bad variable name.


void extract(char * c)

Don't mixchar*s andstrings unless necessary. In this case you can usestrings all the way, so you should defineextract withconst string& sentence as an argument (note thatsentence is also a more descriptive name thanc).

Further it seems that yourextract function is doing too much work: it's extracting words from the sentence into an array, and then printing it in reverse. These two separate steps should be done by two functions:extract (or maybesentence_to_words which is more descriptive) andprint_in_reverse.

You might even want to use 3 steps instead: extract the words, reverse them, then print them. This way your IO code is completely separate from any logic, which is always good. As a bonus point C++ already has a built-in function to reverse an array or vector, so no additional work for you.

Either way you'd need to change yourextract function to either return the extracted words rather thanvoid or take a vector into which to store the extracted words as an argument (by reference).


//char *temp = (char *)malloc(sizeof(char));

This code is commented out anyway (and doesn't do anything sensible from the looks of it), but as a general principle I want to point out that there's rarely a reason to usemalloc overnew in C++.


int ind = 0;while(*c!= NULL){    if(*c!= ' ') // read all chars in a word and store in temp.    {    temp[ind]= temp[ind] + *c;    c++;    }    else if(*c== ' ') // reached end of word    {    c++;    ind++;    }}

Using a vector you can get rid ofind as you can justpush_back into the vector.

Further if you usestrings, you can simplify this part by usingfind to find the next space andsubstr take the substring up to that space.


int length = sizeof(temp)/sizeof(temp[0]);

Note that this will only ever tell you the size of an array if the array's size is known at compile time (which is more or less equivalent to: "spelled out in the code"). So if you want the size of the array to be dynamic, you can't use this. If you use a vector, you can just usetemp.size().


printf("The reversed string is");

As I already said, you shouldn't mixstdio andiostream. There is no reason to useprintf here.


void main()

The correct return value formain isint, notvoid.


char *c = "seattle is good";

Again this should just bestring sentence("seattle is good");. No reason to usechar*.


If I were to write this program, I might do it like this:

#include <string>#include <iostream>#include <string>#include <iostream>#include <vector>#include <algorithm>using std::string;using std::vector;using std::cout;using std::endl;using std::reverse;// Splits a sentence by spaces into a vector of wordsvoid extract(const string& sentence, vector<string>& words){    size_t pos = 0;    while(pos != string::npos)    {          // Find position of next space        int next_space = sentence.find(" ", pos);        // Store everything up to next space in the words vector        words.push_back( sentence.substr(pos, next_space - pos));        // Continue at the next character which is not a space.        pos = sentence.find_first_not_of(" ", next_space);    }}// Prints the strings in the vector separated by spacesvoid print_strings(const vector<string>& strings){    for(size_t i = 0; i < strings.size(); i++) {        cout << strings[i] << " ";    }    cout << endl;}int main(){    string sentence("seattle is good");    vector<string> words;    extract(sentence, words);    reverse(words.begin(), words.end());    print_strings(words);}
answeredMar 11, 2011 at 22:50
sepp2k's user avatar
\$\endgroup\$
3
  • \$\begingroup\$Am trying to see if it is possible to do the same without the temp variable. I wanted to try a inplace replacement and I have this algorithm in mind. Algorithm: 1. Keep a start and end index. Start will be 0 and end will be length of the input string - 1.\$\endgroup\$CommentedMar 12, 2011 at 0:24
  • \$\begingroup\$Actually, it should bestring sentence("seattle is good"); No point in having it constructed and then assigning to it :)\$\endgroup\$CommentedMar 12, 2011 at 16:09
  • \$\begingroup\$FWIW,stdafx.h is not even a C header.\$\endgroup\$CommentedJul 28, 2019 at 4:00
3
\$\begingroup\$

An alternate iterative solution is as follows. This might not be much of an improvement over the more imperative approach above, still a different algorithm might be good to learn.

A simple function that prints out a word that starts from the current character pointer. We loop and print till we get a end-of-string ('\0') or a blank:

#include <iostream>void print_word(const char* x) {    while (*x != ' ' && *x != '\0'){        std::cout << x[0];        x++;    }    std::cout << " ";}

The chief function, that operates from the first letter of a word:

void iterate_words(const char* x) {

We remember where this word has started at pointer x.

    const char *a = x;

We start looking for the start position of the next word (or rest of the sentence). And yes, if the string ends in the meantime, we don't need that position. We just set a flaglastword and exit.

    bool islastword = 0;    while (*a != ' ') {        if (*a == '\0') {            islastword = 1;            break;        }        a++;    }

Now, we have the position of our current word and rest of the sentence. If we print this word, and then call up our functioniterate_words over rest of the sentence, we shall print the sentence in its original form. But, if we do the function call first, then only after the next word has been printed shall we print the current word, i.e. in reverse!

    if (!lastword) iterate_words(a + 1);    print_word(x);}int main() {    iterate_words("hello world");    return 0;}
answeredJan 18, 2016 at 13:09
bob's user avatar
\$\endgroup\$
0
2
\$\begingroup\$

why char ? use string ,use stack or vector to push contents of the word after that read it in reverse order

  #include<vector>   std::string word ="i dont know what to do";   std::<vector> temp;     for(size_t i=0;i<=word.length();i++)      {        temp.push_back(word[i]);       }     //for getting in reverse order     for(size_t j=word.length();j<=0;j--)        std::cout<<temp[j];
answeredApr 23, 2020 at 18:44
sameraze agvvl's user avatar
\$\endgroup\$

You mustlog in to answer this question.