2

ユーザーから短い文章を受け取り、逆の順序で表示するプログラムを作成しようとしています。残念ながら、私は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

4 に答える 4

2

これにアプローチするためのかなりの方法は、次のアルゴリズムです。

  1. ファイルをバッファにロードし、null文字で終了します。
  2. p最後のバッファスロットの場所へのポインタを置きます。
  3. バッファの先頭をp指していないときに、次の手順を実行します。
    • 文字が改行('\n')の場合、
      1. 改行( )を過ぎp+1た文字列をstdoutに送信します。
      2. が指す改行をpヌル文字で上書きします。
    • p1文字の位置をデクリメントします。
  4. 上記のループが終了した後、残りの1行があります。最初の行です。それをstdoutに送信すれば、完了です。

またはそう私は信じるように導かれます。考慮すべき重要なことは次のとおりです。

  1. アルゴリズムは空のファイルで機能しますか?
  2. アルゴリズムは改行のみを含むファイルで機能しますか?
  3. アルゴリズムは、末尾に改行がない複数行のファイルで機能しますか?
  4. アルゴリズムは、末尾に改行がない単一行ファイルで機能しますか?
  5. アルゴリズムは、末尾に改行がある複数行のファイルで機能しますか?
  6. アルゴリズムは、末尾に改行がある単一行ファイルで機能しますか?

そうは言っても、ここに潜在的な候補があります:

#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

更新:ユーザー入力の組み込み

2番目のバージョンのユーザー入力を組み込む例は次のとおりです。

#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;
}
于 2013-02-16T09:32:25.657 に答える
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++拡張が回避されます。(おそらくばかげた方法で)

于 2013-02-16T02:44:56.657 に答える
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;
    }
}
于 2017-05-02T02:59:27.670 に答える
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";
}

行を取得し、バッファリングしてから、逆方向に出力します。

実例

ここでの目標は、メインプログラムのロジックをできるだけ明確にすることです。backwardsとボイラープレートはrange、まさにそのニーズに応えます。

于 2017-05-02T03:46:31.353 に答える