Ответ 1
Введите строки и, когда закончите, нажмите Ctrl + Z (затем Enter), если в Windows или Ctrl + D, если в Linux. Когда вы это сделаете, условие cin>>temp;
внутри цикла for
будет оцениваться как false, и ваша программа выйдет из цикла.
У меня возникают трудности с конкретным фрагментом кода, который я изучаю из "Принципов программирования и практики с использованием С++".
Я не могу получить вывод из цикла, ссылающегося на вектор. Я использую std_lib_facilities и stdafx, потому что книга и MVS сказали мне это.
#include "stdafx.h"
#include "../../std_lib_facilities.h"
int main()
{
vector<string>words;
for(string temp; cin>>temp; )
words.push_back(temp);
cout << "Number of words: " << words.size() << '\n';
}
Это ничего не даст. Я получу приглашение, введите несколько слов, затем введите, затем ничего.
Пробовал некоторые варианты, которые я получил здесь и с других сайтов, например:
//here i tried the libraries the guy used in his code
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
cout << "Please enter a series of words followed by End-of-File: ";
vector<string> words;
string word;
string disliked = "Broccoli";
while (cin >> word)
words.push_back(word);
cout << "\nNumber of words: " << words.size() << endl;
// cycle through all strings in vector
for (int i = 0; i < words.size(); ++i)
{
if (words[i] != disliked)
cout << words[i] << endl;
else
cout << "BLEEP!\n";
}
return 0;
}
Все еще ничего.
После некоторых попыток, устраняя, я вполне уверен, что проблема связана с связью между векторами, потому что все они работают нормально:
int main()
{
vector<string>words = { "hi" };
words.push_back("hello");
cout << words[1] << "\n"; // this will print hello
for (int i = 0; i < words.size();++i) {
cout << words[i] << "\n"; // this will print out all elements
// inside vector words, ( hi, hello)
}
cout << words.size();// this will print out number 2
for (string temp; cin >> temp;) {
words.push_back(temp);
}
cout << words.size();// this won't do anything after i type in some
// words; shouldn't it increase the size of the
// vector?
}
Также это не будет:
int main()
{
vector<string>words = { "hi" };
for (string temp; cin >> temp;) {
words.push_back(temp);
}
cout << words.size();
}
Чего мне не хватает, пожалуйста? Заранее благодарю вас.
Введите строки и, когда закончите, нажмите Ctrl + Z (затем Enter), если в Windows или Ctrl + D, если в Linux. Когда вы это сделаете, условие cin>>temp;
внутри цикла for
будет оцениваться как false, и ваша программа выйдет из цикла.
Во-первых, нет необходимости использовать std_lib_facilities.h
. Это просто что-то, что используется в книге, чтобы избежать того, чтобы каждый пример в книге регулярно включал набор стандартных заголовков или исправлял нестандартное поведение между компиляторами. Это также заголовок, который делает using namespace std
- вы найдете множество примеров (как в SO, так и в более широком Интернете), объясняющих, почему в файле заголовка очень плохое использование using namespace std
.
Во-вторых, нет необходимости использовать stdafx.h
. Это то, что генерируется Microsoft IDE, и обеспечивает средство ускорения компиляции в больших проектах из-за того, как это заставляет компилятор работать с предварительно скомпилированными заголовками. Если вы только ожидаете использовать компиляторы Microsoft, тогда не стесняйтесь заполнять свои ботинки и использовать их. Однако он не является стандартным С++, может (в зависимости от IDE и параметров проекта) включать заголовки, специфичные для Windows, которые не будут работать с компиляторами, отличными от Microsoft, и на форумах, вероятно, будут препятствовать людям, которые используют другие компиляторы, помочь вам, поскольку они будут иметь что ваш код использует Microsoft-специфические расширения, что будет означать, что они, вероятно, не помогут вам.
Первый образец кода можно переписать в стандартном С++ (без использования заголовка выше) в качестве
#include <vector> // for std::vector
#include <string> // for std::string
#include <iostream> // std::cout and other I/O facilities
int main()
{
std::vector<std::string> words;
for(std::string temp; std::cin >> temp; )
words.push_back(temp);
std::cout << "Number of words: " << words.size() << '\n';
}
Прежде чем вы будете взволнованы, у этой проблемы будет такая же проблема (видимо, не заканчивается). Причина в том, что на самом деле условие завершения цикла - std::cin >> temp
завершает цикл только в том случае, если в потоке встречается конец файла или какая-либо другая ошибка.
Итак, если вы наберете
The cow jumped over the moon
std::cin
будет продолжать ждать ввода. Обычно USER запускает и завершает состояние файла. В окнах это требует, чтобы пользователь вводил CTRL-Z
в пустую строку, за которой следует клавиша ввода.
Альтернативой было бы иметь некоторый предварительно согласованный текст, который заставляет цикл выйти, например
#include <vector> // for std::vector
#include <string> // for std::string
#include <iostream> // std::cout and other I/O facilities
int main()
{
std::vector<std::string> words;
for(std::string temp; std::cin >> temp && temp != "zzz"; )
words.push_back(temp);
std::cout << "Number of words: " << words.size() << '\n';
}
что приведет к выходу программы, когда вход содержит слово zzz
. Например
The cow jumped over the moon zzz
Существуют и другие методы, такие как чтение одного символа за раз и остановка, когда пользователь вводит две последовательные строки новой строки. Это требует, чтобы ваш код интерпретировал каждого персонажа и определял, что представляет собой слово. Я оставлю это как упражнение.
Обратите внимание, что в стандартном С++ нет средств для прямого чтения нажатий клавиш - описанные выше проблемы связаны с тем, как работают стандартные потоки и взаимодействуют с хост-системой.
Пользователь также может использовать программу "как есть", помещая один и тот же текст в фактический файл и (когда программа запускается) перенаправляет вход для вашей программы из этого файла. Например your_executable < filename
.