getline从txt文件中读取数据
Getline to read data from txt file
我在使用 getline 命令从简单的 .txt 文件中提取数据时遇到了一些问题。
txt 文件非常简单:一列 400 个数字。我使用一个向量来存储它们,代码如下:
int i = 0;
string line;
vector <double> vec;
while (getline(input, line))
{
vec.push_back(i);
N++;
input >> vec[i];
i++;
}
它正确地创建了一个包含 400 个元素的向量,但忽略了 txt 文件的第一行(我最终得到的是 vec[0] = txt 文件的第 2 行而不是第 1 行)并且第 399 个元素是 399 而不是第 400 行txt 文件。
我尝试了其他几种方法来提取这些数据,但都没有成功。
感谢您的帮助!
编辑:
我根据一些评论编辑了代码:
vector <double> vec;
string line;
double num;
while (getline(input, line))
{
input >> num;
vec.push_back(num);
}
不幸的是,它仍然跳过了我的文本文件的第一行。
编辑 2 --> 解决方案:
感谢您的所有评论,我意识到在同时使用 getline 和 input >> num;
时我做错了什么
问题的解决方法如下:
double num;
vector <double> vec;
while (input >> num)
{
vec.push_back(num);
}
像下面这样更改你的 while 循环:-
while (getline(input, line))
{
vec.push_back(line);
//N++;
//input >> vec[i];
//i++;
}
也可以尝试以下选项
do{
vec.push_back(i);
//N++;
//i++;
}while (input >> vec[i++]);
只需将 std::istream_iterator
传递给 std::vector
构造函数,您就可以将整个文件读入向量,无需循环:
std::vector<int> v{
std::istream_iterator<int>{input},
std::istream_iterator<int>{}
};
例如:
#include <iostream>
#include <iterator>
#include <vector>
#include <exception>
template<class T>
std::vector<T> parse_words_into_vector(std::istream& s) {
std::vector<T> result{
std::istream_iterator<T>{s},
std::istream_iterator<T>{}
};
if(!s.eof())
throw std::runtime_error("Failed to parse the entire file.");
return result;
}
int main() {
auto v = parse_words_into_vector<int>(std::cin);
std::cout << v.size() << '\n';
}
由于再次读取文件,您丢失了第一行 - 这里:
while (getline(input, line))
// ^^^^^^^ Here you read the first line
{
input >> num;
// ^^^^^^^^ Here you will read the second line
你告诉过你想要一个双打矢量 - 比如:
std::vector<double> vec;
所以你应该使用 std::stod
将 getline
读取的行转换为双精度。喜欢:
while (std::getline(input, line))
{
// Convert the text line (i.e. string) to a floating point number (i.e. double)
double tmp;
try
{
tmp = stod(line);
}
catch(std::invalid_argument)
{
// Illegal input
break;
}
catch(std::out_of_range)
{
// Illegal input
break;
}
vec.push_back(tmp);
}
不要在循环内做input >> num;
。
如果你真的想使用 input >> num;
那么你应该 而不是 使用 getline
。也就是说 - 您可以使用任何一个,但 而不是 两者。
您首先在第一次迭代中将 0 放入向量中:
vec.push_back(i);
然后在你读完第一行之后你读下一个字符串,但是从文件中获取的流指针已经在不同的地方,所以你覆盖这个 0 并跳过流中的第一个值。更糟糕的是奇怪地转换为 double:
input >> vec[i];
这样你就不会出错了。
试试这个:
while (std::getline(file, line)) {
//In c++11
vec.emplace_back(std::stod(line));
//In c++ 98, #include <stdlib.h> needed
//vec.push_back(atof(line.c_str()));
}
这假定您始终拥有正确的文件。
我在使用 getline 命令从简单的 .txt 文件中提取数据时遇到了一些问题。
txt 文件非常简单:一列 400 个数字。我使用一个向量来存储它们,代码如下:
int i = 0;
string line;
vector <double> vec;
while (getline(input, line))
{
vec.push_back(i);
N++;
input >> vec[i];
i++;
}
它正确地创建了一个包含 400 个元素的向量,但忽略了 txt 文件的第一行(我最终得到的是 vec[0] = txt 文件的第 2 行而不是第 1 行)并且第 399 个元素是 399 而不是第 400 行txt 文件。
我尝试了其他几种方法来提取这些数据,但都没有成功。
感谢您的帮助!
编辑:
我根据一些评论编辑了代码:
vector <double> vec;
string line;
double num;
while (getline(input, line))
{
input >> num;
vec.push_back(num);
}
不幸的是,它仍然跳过了我的文本文件的第一行。
编辑 2 --> 解决方案:
感谢您的所有评论,我意识到在同时使用 getline 和 input >> num;
时我做错了什么问题的解决方法如下:
double num;
vector <double> vec;
while (input >> num)
{
vec.push_back(num);
}
像下面这样更改你的 while 循环:-
while (getline(input, line))
{
vec.push_back(line);
//N++;
//input >> vec[i];
//i++;
}
也可以尝试以下选项
do{
vec.push_back(i);
//N++;
//i++;
}while (input >> vec[i++]);
只需将 std::istream_iterator
传递给 std::vector
构造函数,您就可以将整个文件读入向量,无需循环:
std::vector<int> v{
std::istream_iterator<int>{input},
std::istream_iterator<int>{}
};
例如:
#include <iostream>
#include <iterator>
#include <vector>
#include <exception>
template<class T>
std::vector<T> parse_words_into_vector(std::istream& s) {
std::vector<T> result{
std::istream_iterator<T>{s},
std::istream_iterator<T>{}
};
if(!s.eof())
throw std::runtime_error("Failed to parse the entire file.");
return result;
}
int main() {
auto v = parse_words_into_vector<int>(std::cin);
std::cout << v.size() << '\n';
}
由于再次读取文件,您丢失了第一行 - 这里:
while (getline(input, line))
// ^^^^^^^ Here you read the first line
{
input >> num;
// ^^^^^^^^ Here you will read the second line
你告诉过你想要一个双打矢量 - 比如:
std::vector<double> vec;
所以你应该使用 std::stod
将 getline
读取的行转换为双精度。喜欢:
while (std::getline(input, line))
{
// Convert the text line (i.e. string) to a floating point number (i.e. double)
double tmp;
try
{
tmp = stod(line);
}
catch(std::invalid_argument)
{
// Illegal input
break;
}
catch(std::out_of_range)
{
// Illegal input
break;
}
vec.push_back(tmp);
}
不要在循环内做input >> num;
。
如果你真的想使用 input >> num;
那么你应该 而不是 使用 getline
。也就是说 - 您可以使用任何一个,但 而不是 两者。
您首先在第一次迭代中将 0 放入向量中:
vec.push_back(i);
然后在你读完第一行之后你读下一个字符串,但是从文件中获取的流指针已经在不同的地方,所以你覆盖这个 0 并跳过流中的第一个值。更糟糕的是奇怪地转换为 double:
input >> vec[i];
这样你就不会出错了。 试试这个:
while (std::getline(file, line)) {
//In c++11
vec.emplace_back(std::stod(line));
//In c++ 98, #include <stdlib.h> needed
//vec.push_back(atof(line.c_str()));
}
这假定您始终拥有正确的文件。