程序找不到回车 return 或换行符。 Returns 超出范围
Program can't find carriage return or newline. Returns out of range
我目前在导航 txt 文件时遇到问题,因此我可以将其读入数组。该程序编译正常,但是当我 运行 它在终端中 returns 时:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::erase: __pos (which is 18446744073709551615) > this->size() (which is 14)
Aborted (core dumped)
代码如下:
#include<cstdlib>
#include<cmath>
#include<fstream>
#include<sstream>
#include<iomanip>
#include<iostream>
#include<string>
#include<cstring>
#include<cassert>
#include<ctime>
#include<cctype>
#include<algorithm>
#include<locale.h>
#include<stdio.h>
#include<functional>
#include<math.h>
using namespace std;
int main(int argc, char**argv)
{
int r=0;
int p=0;
int c=0;
string names[20];
double scores[20][10];
ifstream infile;
infile.open("./bowlers.txt");
for(int r=1;r<=10;r++)
{
getline(infile,names[r]);
p=names[r].find_first_of("\n") ;
names[r].erase(p,2);
for(c=1;c<=5;c++)
{
infile>>scores[r][c];
}
infile.ignore(100,'\n');
}
infile.close();
for(int r=1;r<=10;r++)
{
cout<<fixed<<setprecision(2)<<endl;
cout<<names[r]<<endl;
}
return 0;
}
我使用的 txt 文件如下所示:
charles
123
321
222
rose
432
515
123
Greg
123
553
136
下面是我自己研究这个问题的发现:
- Unix 和 Windows 对 EOL 的处理方式不同。
我的部分问题是:
p=names[r].find_first_of('\n') ;
names[r].erase(p,2);
是导致问题的原因,因为 \n
从未找到它 returns -1,而你不能 .erase
-1?
我已经尝试使用所有可以想到的 \r,
\n
、\r\n
等,但我总是收到大致相同的输出。我还尝试更改 .txt 文件的编码。唯一的区别在于 (which is 14)
。该数字将根据我对 .txt 文件的编码方式而波动。我还打开了 vim 和 :set list
中的 .txt 文件以查看换行符。所以我知道他们在那里。
这只是一个更大的学校项目的部分代码,我对 c++ 还不是很熟悉。谁能指出我正确的方向?我觉得一旦我弄清楚了这部分代码,我就应该能够完成这个项目。
注意:txt 文件只是一个例子,所以不要过多考虑数组的大小或 for 循环中的参数。我已经三次检查了我的数组的大小,以确保我在尝试读入不存在的行时没有问题。
我不知道你为什么需要检测换行符。如果您正在寻找提取姓名和号码的方法,您可以执行以下操作
string word;
int i(0);
while ( infile >> word ){
if(!(i%4)){
//name
std::cout << word << endl;
}else{
//number
}
++i;
}
利用了解文件的确切格式的优势。该文件已经以一种完美且易于操作的方式进行。另外,如果您不知道数据的大小。我鼓励您在固定大小的数组上使用向量。
始终检查查找函数的值 return。示例:
size_t p = names[r].find_first_of("\n");
if (p != string::npos)
names[r].erase(p, 2);
如果找不到 \n
,则 return 值为 string::npos
(可能是 0xFFFFFFFF
或 0xFFFFFFFFFFFFFFFF
),这是无效索引。尝试访问该索引会导致错误。
如评论中所述,names[r]
在这种情况下不包含 \n
。 p
总是 string::npos
并且不需要此操作。
for(c=1;c<=5;c++)
{
infile>>scores[r][c];
}
每个名字下面只有 3 个整数,因此您应该数到 3,而不是 5。此代码应该有效:
for(int r = 1; r <= 10; r++)
{
getline(infile, names[r]);
for(int c = 1; c <= 3; c++)
infile >> scores[r][c];
infile.ignore(100, '\n');
}
或者您可以添加更多错误检查,例如 if (!(infile >> scores[r][c])) break;
我目前在导航 txt 文件时遇到问题,因此我可以将其读入数组。该程序编译正常,但是当我 运行 它在终端中 returns 时:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::erase: __pos (which is 18446744073709551615) > this->size() (which is 14)
Aborted (core dumped)
代码如下:
#include<cstdlib>
#include<cmath>
#include<fstream>
#include<sstream>
#include<iomanip>
#include<iostream>
#include<string>
#include<cstring>
#include<cassert>
#include<ctime>
#include<cctype>
#include<algorithm>
#include<locale.h>
#include<stdio.h>
#include<functional>
#include<math.h>
using namespace std;
int main(int argc, char**argv)
{
int r=0;
int p=0;
int c=0;
string names[20];
double scores[20][10];
ifstream infile;
infile.open("./bowlers.txt");
for(int r=1;r<=10;r++)
{
getline(infile,names[r]);
p=names[r].find_first_of("\n") ;
names[r].erase(p,2);
for(c=1;c<=5;c++)
{
infile>>scores[r][c];
}
infile.ignore(100,'\n');
}
infile.close();
for(int r=1;r<=10;r++)
{
cout<<fixed<<setprecision(2)<<endl;
cout<<names[r]<<endl;
}
return 0;
}
我使用的 txt 文件如下所示:
charles
123
321
222
rose
432
515
123
Greg
123
553
136
下面是我自己研究这个问题的发现:
- Unix 和 Windows 对 EOL 的处理方式不同。
我的部分问题是:
p=names[r].find_first_of('\n') ; names[r].erase(p,2);
是导致问题的原因,因为
\n
从未找到它 returns -1,而你不能.erase
-1?
我已经尝试使用所有可以想到的 \r,
\n
、\r\n
等,但我总是收到大致相同的输出。我还尝试更改 .txt 文件的编码。唯一的区别在于 (which is 14)
。该数字将根据我对 .txt 文件的编码方式而波动。我还打开了 vim 和 :set list
中的 .txt 文件以查看换行符。所以我知道他们在那里。
这只是一个更大的学校项目的部分代码,我对 c++ 还不是很熟悉。谁能指出我正确的方向?我觉得一旦我弄清楚了这部分代码,我就应该能够完成这个项目。
注意:txt 文件只是一个例子,所以不要过多考虑数组的大小或 for 循环中的参数。我已经三次检查了我的数组的大小,以确保我在尝试读入不存在的行时没有问题。
我不知道你为什么需要检测换行符。如果您正在寻找提取姓名和号码的方法,您可以执行以下操作
string word;
int i(0);
while ( infile >> word ){
if(!(i%4)){
//name
std::cout << word << endl;
}else{
//number
}
++i;
}
利用了解文件的确切格式的优势。该文件已经以一种完美且易于操作的方式进行。另外,如果您不知道数据的大小。我鼓励您在固定大小的数组上使用向量。
始终检查查找函数的值 return。示例:
size_t p = names[r].find_first_of("\n");
if (p != string::npos)
names[r].erase(p, 2);
如果找不到 \n
,则 return 值为 string::npos
(可能是 0xFFFFFFFF
或 0xFFFFFFFFFFFFFFFF
),这是无效索引。尝试访问该索引会导致错误。
如评论中所述,names[r]
在这种情况下不包含 \n
。 p
总是 string::npos
并且不需要此操作。
for(c=1;c<=5;c++)
{
infile>>scores[r][c];
}
每个名字下面只有 3 个整数,因此您应该数到 3,而不是 5。此代码应该有效:
for(int r = 1; r <= 10; r++)
{
getline(infile, names[r]);
for(int c = 1; c <= 3; c++)
infile >> scores[r][c];
infile.ignore(100, '\n');
}
或者您可以添加更多错误检查,例如 if (!(infile >> scores[r][c])) break;