如何将<string>具有一定数量单词的向量输出读取到一行?

How to read output of a vector<string> with a certain number of words to a line?

本文关键字:向量 读取 输出 一行 string lt gt 具有一 单词      更新时间:2023-10-16

我正在努力解决一本书中的问题。我正在自学c++,只学到了第三章,但是这个问题真的把我难住了。

问题是:"从din中读取一个单词序列,并将这些值存储在一个向量中。读完所有单词后,处理向量并将每个单词改为大写。打印转换后的元素,一行八个字。"- c++ Primer(第5版)练习3.17

我可以存储在vector中,并将所有单词更改为大写,没有问题。把它们打印出来才是问题所在。

你能帮帮我吗?我很沮丧!!也请保持它真的很好和简单,它只是第3章,我想写答案在那个层次,而不是复杂的(对于我目前的水平)代码。

非常感谢所有的帮助!!

这是我现在的代码:

#include <iostream>
#include <string>
#include <vector>
using std::string; using std::vector; using std::cout; using std::cin; using std::endl;
int main ()
{
    vector<string> v1;  // Create an empty vector
    string words;     // Create a string "words"
    string output;
    while (cin >> words) {
        v1.push_back(words);
    }
    for (auto i = 0; i<v1.size(); ++i){
        for (auto &s : v1) {
            for (auto &c : s)
                c = toupper(c);
        }
        cout << v1[i] << " ";
    }
}

替代Jon的建议,使用模数运算符

for (int i = 0, i < v1.size(); ++i) {
    for (auto &c : v1[i]) {
        c = toupper(c)
    }
    // satisfying 8-per-line requirement
    if (i % 8 == 0) {
        std::cout << std::endl;
    }
    std::cout << v1[i] << " ";
}

一种简单的方法是跟踪当前行到目前为止已打印的单词数,并在该计数超过8时结束该行:

int count = 0;
const int max = 8;
for (const auto& word : words) {
  cout << word << ' ';
  // One more word has been printed.
  ++count;
  // If the count exceeds the maximum number of words per line...
  if (count > max) {
    // ...then move to the next line.
    count = 0;
    cout << 'n';
  }
}

希望您熟悉迭代器,因为您正在使用STL。下面的例子使用了迭代器。

vector<string>::iterator itrbegin = v1.begin();
vector<string>::iterator itrend = v1.end();
int count = 0;
while(itrbegin != itrend)
{
  cout<<*itrbegin;
  count++;
  if(count % 8 == 0)
  {
    cout<<endl;  
  }
 itrbegin++;
}

这应该可以工作并打印出向量。你应该把它放在已经用字符串填充完的向量之后。希望这对你有帮助!

通常您会使用copyostream_iteratorvector复制到cout:

vector<string> words;
copy(words.begin(), words.end(), ostream_iterator<string>(cout, " "));

最后一个参数决定分隔符,在本例中为空格。

beginend复制整个vector。我们想要使用一些东西来代替beginend,这样我们就可以在8块的块中向前移动向量,也许在最后的块中更少。

int chunk_size = 8;
auto chunk_begin = words.begin();
while(disance(chunk_begin, words.end()) >= chunk_size) {
    auto chunk_end = chunk_begin;
    advance(chunk_end, chunk_size);
    copy(chunk_begin, chunk_end, ostream_iterator<string>(cout, " "));
    chunk_begin = chunk_end;
    cout << endl;
}
copy(chunk_begin, words.end(), ostream_iterator<string>(cout, " "));

注:我经常推荐封装。再考虑一下,我们可以封装输出迭代器来跟踪并写一个换行符,而不是在每8次赋值之后写一个空格。这是相当多的工作,但值得记住,因为重用、可读性、代码大小、测试等都会受到影响:

copy(words.begin(), words.end(),
     chunked_ostream_iterator<string>(cout, " ", 8, "n"));

我知道这个线程很老了,但是我在浏览这本书(5版)时遇到了同样的问题,并找到了一个更符合书中解释的内容的解决方案,直到本章(第3章)。本书目前唯一没有涉及的问题是使用模数方法来实现一个比循环迭代器运行速度慢的计数器,但其余的都是从这里开始的。

int main () { vector<string> sentence; string word; while (cin >> word) // add words from input sentence.push_back(word); unsigned cnt = 1; // initialize counter for (auto &w: sentence) { for (auto &c: w) // uppercase word c = toupper(c); cout << w << " "; // print word if (cnt%8 == 0) cout << endl; // eol every 8 counts ++cnt; } cout << endl; // extra eol return 0; }