std::getline() 不忽略白色 space
std::getline() does not ignore white space
我是 C++ 的新手,我在阻止 getline 读取文本文件末尾的换行符时遇到了一些问题。我尝试使用换行符截断它,然后使用“,”传递给定界符,但它不起作用。你能帮我理解发生了什么以及为什么我无法实现我想要做的事情吗?
我编辑了此 post 以更正 getline() 的错误,而不是可用的错误。但是我不知道如何传输此 getline() 字符串以防止使用 '\n' 字符
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
static int Ncol = 5;
int main()
{
int ctr=0,Nrow;
std::string line,line1;
std::ifstream myFile1;
Nrow = 4;
std::cout.precision(15);
std::fixed;
double* input = new double[Nrow*Ncol];
double* ftrue = new double[Nrow];
myFile1.open("./Data_codelink_test/test.txt");
while(ctr<Nrow)
{
std::getline(myFile1,line1,','); // This gives me line1 with the new line character
std::cout<<"Read "<<line1<<std::endl;
input[ctr] = std::stold(line1);
std::cout<<"Stored "<<input[ctr]<<std::endl;
ctr++;
}
myFile1.close();
我的test.txt看起来像这样
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
我想要一个大小为 20 的向量以这种方式存储值
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
我看到的唯一问题(更新:在编辑之前使用 原始 代码)是您调用 std::getline('\n')
的次数 (25) 多于您的实际行数在文件 (4) 中。到达 EOF 时,您不会终止循环。请改用此循环条件:
while ((ctr < (Nrow*Ncol)) && std::getline(myFile1, line))
当 Nrow*Ncol
项已存储在数组中或 std::getline()
无法读取文件中的下一行时,这将结束循环。
也就是说,考虑使用 std::vector
而不是 new[]
。让vector
随着每一行成功读取而动态增长,例如:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
int main()
{
std::ifstream myFile1("./Data_codelink_test/test.txt");
std::vector<double> input;
std::string str;
std::cout << std::fixed << std::setprecision(15);
while (std::getline(myFile1, str))
{
std::istringstream iss(str);
std::getline(iss, str, ',');
std::cout << "Read " << str << std::endl;
input.push_back(std::stold(str));
std::cout << "Stored " << input.back() << std::endl;
}
myFile1.close();
...
}
更新:使用您提供的任何一个代码片段都无法获得您想要的结果。在原始代码中,您可以很好地阅读这些行,但随后您只能提取每行中的第一个数字。在您编辑的代码中,您读取的是逗号分隔的数字,完全不考虑行,因此您会定期读取一个中间有换行符的字符串。
std::getline()
一次只能处理 1 个分隔符。因此,要解析 std::getline()
所拥有的数据类型,您需要 2 个循环 - 一个循环读取每一行,一个循环拆分每一行,例如:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
static int Ncol = 5;
int main()
{
std::ifstream myFile1("./Data_codelink_test/test.txt");
int ctr = 0, Nrow = 4, maxElems = Nrow*Ncol;
std::string str;
double* input = new double[maxElems];
std::cout << std::fixed << std::setprecision(15);
while ((ctr < maxElems) && std::getline(myFile1, str))
{
std::istringstream iss(str);
while ((ctr < maxElems) && std::getline(iss, str, ',')) {
std::cout << "Read " << str << std::endl;
input[ctr] = std::stold(str);
std::cout << "Stored " << input[ctr] << std::endl;
++ctr;
}
}
myFile1.close();
...
}
或者,使用 std::vector
:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
int main()
{
std::ifstream myFile1("./Data_codelink_test/test.txt");
std::vector<double> input;
std::string str;
std::cout << std::fixed << std::setprecision(15);
while (std::getline(myFile1, str))
{
std::istringstream iss(str);
while (std::getline(iss, str, ',')) {
std::cout << "Read " << str << std::endl;
input.push_back(std::stold(str));
std::cout << "Stored " << input.back() << std::endl;
}
}
myFile1.close();
...
}
std::getline
只接受单个字符作为分隔符:
使用两个循环读取数据更清晰如下:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
static int Ncol = 5;
int main()
{
int column=0,Nrow;
std::string line,field;
std::ifstream myFile1;
Nrow = 5;
std::cout.precision(15);
std::fixed;
double* input = new double[Nrow*Ncol];
double* ftrue = new double[Nrow];
myFile1.open("./Data_codelink_test/test.txt");
int row = 0;
while (std::getline(myFile1, line))
{
std::stringstream stream(line);
int column = 0;
while(column < Ncol)
{
std::getline(stream,field,','); // This gives me line1 with the new line character
std::cout<<"Read "<<field<<std::endl;
input[row * Ncol + column] = std::stold(field);
std::cout<<"Stored "<<input[row * Ncol + column]<<std::endl;
column++;
}
row++;
}
myFile1.close();
}
结果是:
我是 C++ 的新手,我在阻止 getline 读取文本文件末尾的换行符时遇到了一些问题。我尝试使用换行符截断它,然后使用“,”传递给定界符,但它不起作用。你能帮我理解发生了什么以及为什么我无法实现我想要做的事情吗?
我编辑了此 post 以更正 getline() 的错误,而不是可用的错误。但是我不知道如何传输此 getline() 字符串以防止使用 '\n' 字符
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
static int Ncol = 5;
int main()
{
int ctr=0,Nrow;
std::string line,line1;
std::ifstream myFile1;
Nrow = 4;
std::cout.precision(15);
std::fixed;
double* input = new double[Nrow*Ncol];
double* ftrue = new double[Nrow];
myFile1.open("./Data_codelink_test/test.txt");
while(ctr<Nrow)
{
std::getline(myFile1,line1,','); // This gives me line1 with the new line character
std::cout<<"Read "<<line1<<std::endl;
input[ctr] = std::stold(line1);
std::cout<<"Stored "<<input[ctr]<<std::endl;
ctr++;
}
myFile1.close();
我的test.txt看起来像这样
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
1,2,3,4,5
我想要一个大小为 20 的向量以这种方式存储值
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
1
2
3
4
5
我看到的唯一问题(更新:在编辑之前使用 原始 代码)是您调用 std::getline('\n')
的次数 (25) 多于您的实际行数在文件 (4) 中。到达 EOF 时,您不会终止循环。请改用此循环条件:
while ((ctr < (Nrow*Ncol)) && std::getline(myFile1, line))
当 Nrow*Ncol
项已存储在数组中或 std::getline()
无法读取文件中的下一行时,这将结束循环。
也就是说,考虑使用 std::vector
而不是 new[]
。让vector
随着每一行成功读取而动态增长,例如:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
int main()
{
std::ifstream myFile1("./Data_codelink_test/test.txt");
std::vector<double> input;
std::string str;
std::cout << std::fixed << std::setprecision(15);
while (std::getline(myFile1, str))
{
std::istringstream iss(str);
std::getline(iss, str, ',');
std::cout << "Read " << str << std::endl;
input.push_back(std::stold(str));
std::cout << "Stored " << input.back() << std::endl;
}
myFile1.close();
...
}
更新:使用您提供的任何一个代码片段都无法获得您想要的结果。在原始代码中,您可以很好地阅读这些行,但随后您只能提取每行中的第一个数字。在您编辑的代码中,您读取的是逗号分隔的数字,完全不考虑行,因此您会定期读取一个中间有换行符的字符串。
std::getline()
一次只能处理 1 个分隔符。因此,要解析 std::getline()
所拥有的数据类型,您需要 2 个循环 - 一个循环读取每一行,一个循环拆分每一行,例如:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
static int Ncol = 5;
int main()
{
std::ifstream myFile1("./Data_codelink_test/test.txt");
int ctr = 0, Nrow = 4, maxElems = Nrow*Ncol;
std::string str;
double* input = new double[maxElems];
std::cout << std::fixed << std::setprecision(15);
while ((ctr < maxElems) && std::getline(myFile1, str))
{
std::istringstream iss(str);
while ((ctr < maxElems) && std::getline(iss, str, ',')) {
std::cout << "Read " << str << std::endl;
input[ctr] = std::stold(str);
std::cout << "Stored " << input[ctr] << std::endl;
++ctr;
}
}
myFile1.close();
...
}
或者,使用 std::vector
:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
int main()
{
std::ifstream myFile1("./Data_codelink_test/test.txt");
std::vector<double> input;
std::string str;
std::cout << std::fixed << std::setprecision(15);
while (std::getline(myFile1, str))
{
std::istringstream iss(str);
while (std::getline(iss, str, ',')) {
std::cout << "Read " << str << std::endl;
input.push_back(std::stold(str));
std::cout << "Stored " << input.back() << std::endl;
}
}
myFile1.close();
...
}
std::getline
只接受单个字符作为分隔符:
使用两个循环读取数据更清晰如下:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
static int Ncol = 5;
int main()
{
int column=0,Nrow;
std::string line,field;
std::ifstream myFile1;
Nrow = 5;
std::cout.precision(15);
std::fixed;
double* input = new double[Nrow*Ncol];
double* ftrue = new double[Nrow];
myFile1.open("./Data_codelink_test/test.txt");
int row = 0;
while (std::getline(myFile1, line))
{
std::stringstream stream(line);
int column = 0;
while(column < Ncol)
{
std::getline(stream,field,','); // This gives me line1 with the new line character
std::cout<<"Read "<<field<<std::endl;
input[row * Ncol + column] = std::stold(field);
std::cout<<"Stored "<<input[row * Ncol + column]<<std::endl;
column++;
}
row++;
}
myFile1.close();
}
结果是: