你打算這是下面的算法接近相當方式:
- 將文件加載到一個緩衝區,用空字符終止它。
- 將指針
p
定位到最後一個緩衝槽的位置。
- 雖然
p
沒有指向緩衝區開始執行以下操作:
- 如果字符是一個換行符(
'\n'
)然後
- 發送字符串過去換行(
p+1
)到標準輸出。
- 用空字符覆蓋
p
指向的換行符。
- 減量
p
退回一個字符位置。
- 上述循環結束後,剩下一行:第一個。發送到標準輸出,你就完成了。
左右我被引導相信。需要考慮的重要事項如下:
- 該算法是否適用於空文件?
- 該算法是否僅與包含換行符的文件一起使用?
- 該算法是否適用於多行文件WITH NO拖尾換行符?
- 該算法是否可以在單行文件中使用WITH NO拖尾換行符?
- 該算法是否適用於帶有拖尾換行符的多行文件?
- 該算法是否適用於帶有拖尾換行符的單行文件?
話雖這麼說,這裏是一個潛在的候選人:
#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
UPDATE:結合用戶輸入
結合用戶輸入的第二個版本將是一個例子:
#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;
}
是std :: string和反向迭代器的一個選項嗎? – billz 2013-02-16 02:34:22
當您從用戶讀取字符串時,請將其複製並推入堆棧。然後彈出堆棧直到它爲空 – James 2013-02-16 02:36:00
@billz OP正試圖重新實現'tac'。 string.reverse()將不會提供。 – kay 2013-02-16 02:37:49