c ++使用指针以相反的顺序显示句子

时间:2013-02-16 02:33:10

标签: c++

我正在尝试构建一个程序,该程序从用户那里获取短句并以相反的顺序显示它们。不幸的是,我刚开始使用c ++我需要知道这样做。 例如:如果用户输入了输入:

I like the red color
blue is also nice
and green is lovely
but I don't like orange

输出:

but I don't like orange
and green is lovely
blue is also nice
I like the red color

提前致谢!

#include<iostream>
#include<string>
using namespace std;

const int SIZE= 500;

int main()
{

   const int SIZE = 500;
   char mystring[SIZE];
int i;
for(i=0; i<SIZE; i++)
{

    cout<<"Enter a string: ";
    cin.getline(mystring, SIZE);
    } while (mystring != 0);

       char * reverse= new char[strlen(mystring) + 1];
        char *p1 = mystring+ strlen(mystring);
        char *p2 = reverse;


        while(p1 != mystring)
        {
        p1--;
        *p2= *p1;
        p2++;
    }

    *p2 = '\0';
    cout << reverse<<endl;


   system("PAUSE");
   return 0;
}

4 个答案:

答案 0 :(得分:2)

您打算采用的相当多的方法是以下算法:

  1. 将文件加载到缓冲区中,并使用null char终止它。
  2. 将指针p放在最后一个缓冲区插槽的位置。
  3. 虽然p未指向缓冲区的开头,但请执行以下操作:
    • 如果字符是换行符('\n')则
      1. 将字符串过去新行(p+1)发送到stdout。
      2. 使用null char覆盖p指向的换行符。
    • 减少p一个字符位置。
  4. 完成上述循环后,剩下一行:第一行。发送给stdout,你就完成了。
  5. 或者让我相信。需要考虑的重要事项如下:

    1. 算法是否适用于空文件?
    2. 算法是否适用于仅包含换行符的文件?
    3. 算法是否适用于多行文件,没有尾随换行符?
    4. 算法是否适用于单行文件,没有尾随换行符?
    5. 算法是否适用于带有尾随换行符的多行文件?
    6. 算法是否适用于包含尾随换行符的单行文件?
    7. 话虽如此,这是一个潜在的候选人:

      #include <iostream>
      #include <fstream>
      #include <iterator>
      #include <vector>
      using namespace std;
      
      int main(int argc, char *argv[])
      {
          // assume the file to reverse-print is the first
          //  command-line parameter. if we don't have one
          //  we need to leave now.
          if (argc < 2)
              return EXIT_FAILURE;
      
          // will hold our file data
          std::vector<char> data;
      
          // open file, turning off white-space skipping
          ifstream inf(argv[1]);
          inf.seekg(0, inf.end);
          size_t len = inf.tellg();
          inf.seekg(0, inf.beg);
      
          // resize buffer to hold (len+1) chars
          data.resize(len+1);
          inf.read(&data[0], len);
          data[len] = 0; // terminator
      
          // walk the buffer backwards. at each newline, send
          //  everything *past* it to stdout, then overwrite the
          //  newline char with a nullchar (0), and continue on.
          char *start = &data[0];
          char *p = start + (data.size()-1);
          for (;p != start; --p)
          {
              if (*p == '\n')
              {
                  if (*(p+1))
                      cout << (p+1) << endl;
                  *p = 0;
              }
          }
      
          // last line (the first line)
          cout << p << endl;
      
          return EXIT_SUCCESS;
      }
      

      <强>输入

      I like the red color
      blue is also nice
      and green is lovely
      but I don't like orange
      

      <强>输出

      but I don't like orange
      and green is lovely
      blue is also nice
      I like the red color
      

      一种相当简单的方法

      很多 这样做的简单方法,我将在整个过程中解释评论中的每一步。您有可能无法使用此类内容,但是当您可以时,了解您可以使用的内容非常重要:

      #include <iostream>
      #include <fstream>
      #include <iterator>
      #include <vector>
      using namespace std;
      
      int main(int argc, char *argv[])
      {
          // assume the file to reverse-print is the first
          //  command-line parameter. if we don't have one
          //  we need to leave now.
          if (argc < 2)
              return EXIT_FAILURE;
      
          // collection that will hold our lines of text
          vector<string> lines;
      
          // read lines one at a time until none are returned
          //  pushing each line in to our vector.
          ifstream inf(argv[1]);
          string line;
          while (getline(inf, line))
              lines.push_back(line);
          inf.close();
      
          // a LOT happens in the next single line of code, and
          //  I will try to describe each step along the way.
          //
          // we use std::copy() to copy all "items" from
          //   a beginning and ending iterator pair. the
          //   target of the copy is another iterator.
          //
          //  our target iterator for our formatted ouput
          //   is a special iterator class designed to
          //   perform an output-stream insertion operation
          //   (thats the << operator) to the stream it is
          //   constructed with (in our case cout) using each
          //   item we give it from our copy-iteration. to use
          //   this class the "copied" item must support the
          //   traditional insertion operator <<, which of
          //   course, std::string does. after each item is
          //   written, the provided suffix (in our case \n)
          //   is written as well. without this all the lines
          //   would be ganged together.
          //
          //  lastly, to glue this together (and the whole
          //   reason we're here), we use a pair of special
          //   iterators designed to  work just like the regular
          //   begin() and end() iterators you're familiar with,
          //   when traversing forward in a sequence, but these
          //   ones, rbegin() and rend(), move from the last
          //   item in the sequence to the first item, which is
          //   *exactly* what we need.
      
          copy(lines.rbegin(), lines.rend(), 
               ostream_iterator<string>(cout, "\n"));
      
          // and thats it.
          return EXIT_SUCCESS;
      }
      

      <强>输入

      I like the red color
      blue is also nice
      and green is lovely
      but I don't like orange
      

      <强>输出

      but I don't like orange
      and green is lovely
      blue is also nice
      I like the red color
      

      更新:合并用户输入

      合并第二个版本的用户输入的示例是:

      #include <iostream>
      #include <iterator>
      #include <vector>
      using namespace std;
      
      int main(int argc, char *argv[])
      {
          // collection that will hold our lines of text
          vector<string> lines;
          do
          {   // prompt the user
              cout << "Sentance (<enter> to exit): ";
              string line;
              if (!getline(cin, line) || line.empty())
                  break;
              lines.push_back(line);
          } while (true);
      
          // send back to output using reverse iterators
          //  to switch line order.
          copy(lines.rbegin(), lines.rend(),
               ostream_iterator<string>(cout, "\n"));
      
          return EXIT_SUCCESS;
      }
      

答案 1 :(得分:1)

可能是这样的:

#include <string>
#include <iostream>
#include <vector>
using namespace std;
// include headers and avoid having to use std:: all the time
int main(){
    vector<string> data;
    string line;
    do{
        std::getline(std::cin, line);
        data.push_back( line );
    }while( cin );//read lines and store to a vector
    for (int i=data.size()-1;i>=0;--i)// traverse the vector in a reversed order (maybe size_t for i would be better)
        cout<<data[i]<<endl;
}

看起来这是一些功课,可能你只能使用一些功能。 如果你坚持,我们可以写一个家庭作业安全版本:

// this is just intended to illustrate how RIDICULOUS it is not to use STL features.
#include <cstring>
#include <cstdio>
#include <cstdlib>
int main(){
#define MAXLEN (10000)
    char* buffer = (char*)malloc(MAXLEN);//allocate space from heap
    char* buffer_ptr = buffer + 1;
    *buffer = '\0';//string terminator
    while( fgets(buffer_ptr,buffer+MAXLEN-buffer_ptr , stdin ) ){
        buffer_ptr += strlen(buffer_ptr);
        ++buffer_ptr;// reserve the '\0'
    }
    buffer_ptr -= 2;
    while(buffer_ptr >= buffer){
        if (!*buffer_ptr)// find end of string
            fputs(buffer_ptr+1,stdout);
        --buffer_ptr;// traverse backward
    }
    free(buffer);//free space
}

尽可能避免C ++扩展。 (以一种可能的荒谬方式)

答案 2 :(得分:0)

#include<iostream>
using namespace std;

int main(){
    char str[100][100];
    for(int i =0; i < 10 ; i++) {
        cin.getline(str[i],100);
    }
    for(int i = 9 ; i >=0 ; i--) {
        cout<<str[i]<<endl;
    }
}

答案 3 :(得分:0)

这是如何做到的。

template<class It>
struct range_t {
  It b; It e;

  It begin() const { return b; }
  It end() const { return e; }
};

template<class It>
range_t<It> range(It s, It f) {
  return {s,f};
}

range( start, finish )是一个帮助程序,可让您创建一个可以for(:)迭代的范围。

template<class C>
auto backwards(C&& c) {
  using std::rbegin; using std::rend;
  return range( rbegin(c), rend(c) );
}

backwards(container)返回一个向后迭代容器的范围。

一旦我们编写了上面的库代码,就完成了所有繁重的工作。剩下的代码几乎和一样漂亮:

int main() {
  std::cout << "Enter some text (blank line to finish):\n";
  std::string line;
  std::vector<std::string> lines;
  while (std::getline(std::cin, line))
    lines.push_back(line);
  for (auto&& line:backwards(lines))
    std::cout << line << "\n";
}

我们得到线条,缓冲它们,然后向后打印。

Live example

这里的目标是使主程序逻辑尽可能清晰。 backwardsrange样板只是满足了这一需求。