我正在尝试用 getline 填充矢量数组,怎么了?
I am trying to fill vector array with getline, what's wrong?
我想用一些行填充向量数组,但我没有得到相同的结果。我的代码有什么问题?
using namespace std;
vector<string> calling(int n){
vector<string> file(n);
int a=0;
while(n){
getline(cin,file[a]);
cin.ignore();
a++;
n--;
}
return file;
}
int main() {
int n;
cin >> n;
vector<string> hrml = calling(n);
int a=0;
while(n){
cout << hrml[a] <<endl;
a++;
n--;
}
return 0;
}
输入:
3
aaaa aaa aa
bb b bbbb
c cc ccc
输出:
aaaa aaa aa
bb b bbbb
在 getline()
之后不需要 std::cin.ignore()
,因为后者 'eats' 是流中的换行符。根据 getline() docs:
Extracts characters from input and appends them to str until one of
the following occurs (checked in the order listed):
(...)
b) the next available input character is delim, as tested by
Traits::eq(c, delim), in which case the delimiter character is
extracted from input, but is not appended to str.
在 std::cin >> n
之后你确实需要 std::cin.ignore()
虽然按回车键你已经将换行符放入流中并且它将被 getline 吃掉,这将 return结果是一个空字符串。
@DimChtz 回答了你的问题,但我想我会告诉你如何使用 for 循环,因为你似乎喜欢笨拙的 while 循环:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
vector<string> calling(int n)
{
vector<string> file(n);
//for loop
for (int i=0; i<n; i++) {
getline(cin, file[i]);
}
return file;
}
int main() {
int n;
cin >> n;
cin.ignore();
vector<string> hrml = calling(n);
//for each loop (C++11)
for (auto & str : hrml) {
cout << str << endl;
}
return 0;
}
这是几个因素的组合。
读取输入中的第一个数字 3
,不会将 "cursor" 移到下一行;它只是将它移过数字。当你下次调用 getline
时,它 returns 一个大小为 0 的 std::string
,因为它抓住了字符末尾和行尾之间的 space,这是没什么。
然后,因为您将该数字用作要读取的字符串的明确数量,所以您正好读取 3 行:""
、"aaaa aaa aa"
和 "bb b bbbb"
。
因此您的输出缺少 'c'
行。
此处最简单的解决方案是在调用 calling
之前强制额外调用 getline
。 (我从你的代码中删除了 using namespace std;
因为它是 bad practice)
int main() {
int n;
std::cin >> n;
std::string line;
std::getline(std::cin, line);
然后,我们可以重写calling
不需要整型参数:
std::vector<std::string> calling(){
std::vector<std::string> file;
std::string line;
while(std::getline(std::cin, line)){
file.push_back(std::move(line));
}
return file;
}
(如果您在控制台中进行测试,并且需要一些东西来标记行尾,请使用 Ctrl+ Windows 上的 Z 或 UNIX 上的 Ctrl+D。)
将调用行更改为:
std::vector<std::string> hrml = calling();
或者,如果您使用的是 C++11(并且不介意丢失显式可见的类型声明):
auto hrml = calling();
只要我们在这里,我们就可以编写一个更好的循环来打印向量的内容:
for(size_t i = 0; i < hrml.size(); i++) {
std::cout << hrml[i] << std::endl;
}
或者,如果我们使用 C++11:
for(std::string const& line : hrml) {
std::cout << line << std::endl;
}
而且,如果允许您更改输入文件的格式,我们可以首先放弃读取数字,从而生成更小且更易于调试的程序:
#include<iostream>
#include<string>
#include<vector>
std::vector<std::string> calling(){
std::vector<std::string> file;
std::string line;
while(std::getline(std::cin, line)) {
file.push_back(std::move(line));
}
return file;
}
int main() {
std::vector<std::string> hrml = calling();
for(std::string const& line : hrml) {
std::cout << line << std::endl;
}
return 0;
}
这条语句
cin >> n;
不从输入缓冲区中删除换行符。结果,函数 getline
的以下调用读取空字符串,直到遇到换行符。
函数中的这条语句
cin.ignore();
没有意义。你应该在这个语句之后放置一个类似的语句
cin >> n;
此外,如果您正在处理 int
类型的对象,您应该检查它是否不小于零。
考虑到这一点,程序可以看成下面的样子。
#include <iostream>
#include <string>
#include <vector>
#include <limits>
using namespace std;
vector<string> calling( int n )
{
vector<string> file;
if ( n > 0 )
{
file.reserve( n );
string s;
while ( n-- && getline( cin, s ) ) file.push_back( s );
}
return file;
}
int main()
{
int n = 0;
cin >> n;
cin.ignore( numeric_limits<streamsize>::max(), '\n' );
vector<string> hrml = calling(n);
for ( const string &s : hrml ) cout << s << '\n';
return 0;
}
我想用一些行填充向量数组,但我没有得到相同的结果。我的代码有什么问题?
using namespace std;
vector<string> calling(int n){
vector<string> file(n);
int a=0;
while(n){
getline(cin,file[a]);
cin.ignore();
a++;
n--;
}
return file;
}
int main() {
int n;
cin >> n;
vector<string> hrml = calling(n);
int a=0;
while(n){
cout << hrml[a] <<endl;
a++;
n--;
}
return 0;
}
输入:
3
aaaa aaa aa
bb b bbbb
c cc ccc
输出:
aaaa aaa aa
bb b bbbb
在 getline()
之后不需要 std::cin.ignore()
,因为后者 'eats' 是流中的换行符。根据 getline() docs:
Extracts characters from input and appends them to str until one of the following occurs (checked in the order listed): (...)
b) the next available input character is delim, as tested by Traits::eq(c, delim), in which case the delimiter character is extracted from input, but is not appended to str.
在 std::cin >> n
之后你确实需要 std::cin.ignore()
虽然按回车键你已经将换行符放入流中并且它将被 getline 吃掉,这将 return结果是一个空字符串。
@DimChtz 回答了你的问题,但我想我会告诉你如何使用 for 循环,因为你似乎喜欢笨拙的 while 循环:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
vector<string> calling(int n)
{
vector<string> file(n);
//for loop
for (int i=0; i<n; i++) {
getline(cin, file[i]);
}
return file;
}
int main() {
int n;
cin >> n;
cin.ignore();
vector<string> hrml = calling(n);
//for each loop (C++11)
for (auto & str : hrml) {
cout << str << endl;
}
return 0;
}
这是几个因素的组合。
读取输入中的第一个数字 3
,不会将 "cursor" 移到下一行;它只是将它移过数字。当你下次调用 getline
时,它 returns 一个大小为 0 的 std::string
,因为它抓住了字符末尾和行尾之间的 space,这是没什么。
然后,因为您将该数字用作要读取的字符串的明确数量,所以您正好读取 3 行:""
、"aaaa aaa aa"
和 "bb b bbbb"
。
因此您的输出缺少 'c'
行。
此处最简单的解决方案是在调用 calling
之前强制额外调用 getline
。 (我从你的代码中删除了 using namespace std;
因为它是 bad practice)
int main() {
int n;
std::cin >> n;
std::string line;
std::getline(std::cin, line);
然后,我们可以重写calling
不需要整型参数:
std::vector<std::string> calling(){
std::vector<std::string> file;
std::string line;
while(std::getline(std::cin, line)){
file.push_back(std::move(line));
}
return file;
}
(如果您在控制台中进行测试,并且需要一些东西来标记行尾,请使用 Ctrl+ Windows 上的 Z 或 UNIX 上的 Ctrl+D。)
将调用行更改为:
std::vector<std::string> hrml = calling();
或者,如果您使用的是 C++11(并且不介意丢失显式可见的类型声明):
auto hrml = calling();
只要我们在这里,我们就可以编写一个更好的循环来打印向量的内容:
for(size_t i = 0; i < hrml.size(); i++) {
std::cout << hrml[i] << std::endl;
}
或者,如果我们使用 C++11:
for(std::string const& line : hrml) {
std::cout << line << std::endl;
}
而且,如果允许您更改输入文件的格式,我们可以首先放弃读取数字,从而生成更小且更易于调试的程序:
#include<iostream>
#include<string>
#include<vector>
std::vector<std::string> calling(){
std::vector<std::string> file;
std::string line;
while(std::getline(std::cin, line)) {
file.push_back(std::move(line));
}
return file;
}
int main() {
std::vector<std::string> hrml = calling();
for(std::string const& line : hrml) {
std::cout << line << std::endl;
}
return 0;
}
这条语句
cin >> n;
不从输入缓冲区中删除换行符。结果,函数 getline
的以下调用读取空字符串,直到遇到换行符。
函数中的这条语句
cin.ignore();
没有意义。你应该在这个语句之后放置一个类似的语句
cin >> n;
此外,如果您正在处理 int
类型的对象,您应该检查它是否不小于零。
考虑到这一点,程序可以看成下面的样子。
#include <iostream>
#include <string>
#include <vector>
#include <limits>
using namespace std;
vector<string> calling( int n )
{
vector<string> file;
if ( n > 0 )
{
file.reserve( n );
string s;
while ( n-- && getline( cin, s ) ) file.push_back( s );
}
return file;
}
int main()
{
int n = 0;
cin >> n;
cin.ignore( numeric_limits<streamsize>::max(), '\n' );
vector<string> hrml = calling(n);
for ( const string &s : hrml ) cout << s << '\n';
return 0;
}