A simple reverse sentence in C ++

I am trying to create a program to solve a problem in a textbook that I bought recently, and it just drives me crazy.

I need to create a reverse of the sentence, so I get the following:

Input = "To do or not, no attempt." Output = "try. No no, do or Do"

Here is what I have so far:

void ReverseString::reversalOperation(char str[]) { char* buffer; int stringReadPos, wordReadPos, writePos = 0; // Position of the last character is length -1 stringReadPos = strlen(str) - 1; buffer = new char[stringReadPos+1]; while (stringReadPos >= 0) { if (str[stringReadPos] == ' ') { wordReadPos = stringReadPos + 1; buffer[writePos++] = str[stringReadPos--]; while (str[wordReadPos] != ' ') { buffer[writePos] = str[wordReadPos]; writePos++; wordReadPos++; } } else { stringReadPos--; } } cout << str << endl; cout << buffer << endl; } 

I was sure that I was on the right track, but all I get for the conclusion is the very first word ("try"). I have looked at this code for so long that I cannot succeed. Initially, I checked the inside looking for the '/ 0' character, but it didn’t seem to me, so I took it.

+4
source share
7 answers

In the interest of science, I tried to get your code to work as it is. Yes, actually this is not C ++ - a way to do something, but instructive nonetheless.

Of course, this is just one of millions of ways to do the job. I will leave this as an exercise for you to remove the finite space that this code leaves in the output;)

I commented on my changes with "EDIT".

 char* buffer; int stringReadPos, wordReadPos, writePos = 0; // Position of the last character is length -1 stringReadPos = strlen(str) - 1; buffer = new char[stringReadPos+1]; while (stringReadPos >= 0) { if ((str[stringReadPos] == ' ') || (stringReadPos == 0)) // EDIT: Need to check for hitting the beginning of the string { wordReadPos = stringReadPos + (stringReadPos ? 1 : 0); // EDIT: In the case we hit the beginning of the string, don't skip past the space //buffer[writePos++] = str[stringReadPos--]; // EDIT: This is just to grab the space - don't need it here while ((str[wordReadPos] != ' ') && (str[wordReadPos] != '\0')) // EDIT: Need to check for hitting the end of the string { buffer[writePos] = str[wordReadPos]; writePos++; wordReadPos++; } buffer[writePos++] = ' '; // EDIT: Add a space after words } stringReadPos--; // EDIT: Decrement the read pos every time } buffer[writePos] = '\0'; // EDIT: nul-terminate the string cout << str << endl; cout << buffer << endl; 
+2
source

If you don’t feel masochists, throw away your existing code and start with std::vector and std::string (preferably std::vector<std::string> ). Add std::copy with the rbegin and rend vector, and you pretty much did.

+5
source

It is very simple in C ++ using the standard library:

 std::vector< std::string > sentence; std::istringstream input( str ); // copy each word from input to sentence std::copy( (std::istream_iterator< std::string >( input )), std::istream_iterator< std::string >() , std::back_inserter( sentence ) ); // print to cout sentence in reverse order, separated by space std::copy( sentence.rbegin(), sentence.rend() , (std::ostream_iterator< std::string >( std::cout, " " )) ); 
+5
source

I see the following errors in your code:

  • the last char of the buffer is not set to 0 (this will cause a failure in cout <
  • in the inner loop you should check str[wordReadPos] != ' ' && str[wordReadPos] != 0 , otherwise when scanning the first word it will never find the trailing space
+2
source

Since you are using a char array, you can use the C string library. This will be much simpler if you use strtok: http://www.cplusplus.com/reference/clibrary/cstring/strtok/

This will require the use of a pointer, but it will make your life a lot easier. Your separator will be "".

+1
source

What is where there are problems with your code and what more cplusplusish ways to do is still well written. I would like to add, however, that the methodology

  • write a function / program for implementing the algorithm;
  • see if it works;
  • if it is not, look at the code until you get where the problem is

not too productive. What can help you solve this problem here, and many other problems in the future, is the debugger (and the bad man debugger printf). This will allow you to see how your program works step by step, what happens to data, etc. In other words, you can see which parts of it work the way you expect, and which behave differently. If you are on * nix, feel free to try gdb.

+1
source

Here is another version of C ++. Although I believe that simplicity is more important than style in this case. The basic algorithm is simple enough, flip the words, and then flip the entire line.

You can write C code that was as obvious as the C ++ version. I do not think it is necessarily wrong to write code that is not defiantly C ++ here.

 void word_reverse(std::string &val) { size_t b = 0; for (size_t i = 0; i < val.size(); i++) { if (val[i] == ' ') { std::reverse(&val[b], &val[b]+(i - b)); b = ++i; } } std::reverse(&val[b], &val[b]+(val.size() - b)); std::reverse(&val[0], &val[0]+val.size()); } TEST(basic) { std::string o = "Do or do not, there is no try."; std::string e = "try. no is there not, do or Do"; std::string a = o; word_reverse(a); CHECK_EQUAL( e , a ); } 

Having multiple, leading, or trailing spaces can be a degenerate case, depending on how you really want them to behave.

0
source

Source: https://habr.com/ru/post/1380454/


All Articles