[英]getline() is repeatedly reading the first line of my file
我不知道是否有人会及时看到这个,但我会尝试...我在一个介绍性的c ++课程(本科生),我有一个作业,应该是星期一早上...(是的!我知道我有拖延:),)
好。 我必须以这种形式阅读学生记录:
Adriana,Smith,692493955,50,43,52,86,74,83
Adrienne,Johnson,480562092,75,72,93,71,81,89
Bla, Bla, Bla
从一个文件(最多200个)并对它们进行排序。
我已设法完成所有其他必要的功能,但无法验证它们。
我创建了一个函数,它应该打开文件,读入每一行,并在每个令牌中读取每个令牌,并将它们存储在一个临时数组中。 这个tempArr [9]在进入真实数组之前进行验证[9] [200]。
我已经设法打开文件,在第一行读取并将其标记为一个数组,但是当while循环重复时,它再次读入文件的第一行,因此当我打印出真实数组时,我得+ /第一记录的-200倍。
我在cplusplus.com上阅读并重读了我的手册,getline()信息,在论坛中搜索并将我的代码切换了大约一百万次。
PLEEEEAAASSSSEEE帮助!
这是fn:
void getFile(std::string realArray[][200], const int ROW_SIZE)
{
std::string filename, token, line;
int positionLine(0);
int positionToken(0);
int row(0);
int numOfLine(0);
const int ROWS (9);
const int MAX_RECORDS (200);
std::string tempArray[ROWS];
std::cout << "Please enter the desired filename with it's extension:\t ";
std::cin >> filename;
const char *file=filename.c_str();
std::ifstream input(file, std::ios::in);
while (!input.is_open())
{
std::cout << "The file did not open correctly. \n\nPlease enter a valid filename.\n";
std::cin >> filename;
const char *file=filename.c_str();
std::ifstream input(file, std::ios::in);
}
while (input.good() && numOfLine < MAX_RECORDS)
{
getline (input,line);
std::istringstream inputss (line);
while (getline(inputss, token, ',') && row < ROWS )
{
tempArray[row] = token;
row++;
}
numOfLine++;
validateData (tempArray,ROWS , numOfLine);
storeData(tempArray, ROWS, realArray, ROW_SIZE, numOfLine);
}
if (numOfLine == MAX_RECORDS)
{
std::cout << "The maximum number of records to be read (" << MAX_RECORDS << ") has been reached.\n";
}
}
PS我正在使用visual studio 2010,我的文件是* .dos
哦,我拿出来了
using namespace std;
因为它给了:cout是一个模棱两可的错误。
谢谢。
从哪儿开始!!!!
不好的做法。 每行一个!
std::string filename, token, line;
这些是未使用的。 删除它们。
int positionLine(0);
int positionToken(0);
不要将指向字符串的指针提取到新变量中。
如果文件名被更改,则文件变为无效。
结果传递给函数时使用它是安全的。
const char *file=filename.c_str();
std::ifstream input(file, std::ios::in);
所以你应该这样做。
std::ifstream input(file.c_str());
这里。 您正在声明一个全新的变量input
。 此变量与其他变量input
无关。 当这个版本在while循环结束时超出范围时会被销毁。
while (!input.is_open())
{
// <STUFF DELETED>
std::ifstream input(file, std::ios::in);
}
这是一个非常常见的错误。
在这里测试良好状态通常是错误的。 这是因为当您点击文件末尾时,您希望循环退出。 但是最后一次读取实际上是读取但不是超过文件末尾,因此它不会触发EOF标志并重新进入循环。 然后下一次读取将失败:
while (input.good() && numOfLine < MAX_RECORDS)
{
getline (input,line);
更好的版本是:
while (getline (input,line) && numOfLine < MAX_RECORDS)
{
在这里你得到正确的:
while (getline(inputss, token, ',') && row < ROWS )
{
在这里,您将行递增到索引到tempArray
。 但我看不到该行重置为0的位置。
tempArray[row] = token;
row++;
基于Bo的下面的通讯。
从技术上讲,这样做没有错:
const char *file=filename.c_str();
std::ifstream input(file, std::ios::in);
此处file
立即使用,不再使用。 根据经验,我发现通过这样做,你已经在上下文中引入了一个新的变量,其他人可以随意重复使用。 通常这不是问题,但是这个特定指针可能无形地变为无效(如果修改了文件名对象,那么文件指针可能会变得无效)。
这是一个维护问题,当您有多个开发人员修改代码时尤其危险。 如果变量file
稍后在代码中由开发人员'A'和开发人员'B'重新使用,则会出现并添加修改变量filename
代码,现在您处于危险的情况。
因此, 不存储可能变得无形无效的指针总是更安全。 因此,使用它们的唯一安全方法是作为功能的参数。
std::ifstream input(filename.c_str(), std::ios::in);
我最近遇到的另一种情况是在略有不同的背景下出现同样的问题:
QString path(<Some String>);
char* file = path.toLatin1().data();
readFile(file);
这里的问题是toLatin()返回QByteArray的对象。 此对象由值返回,未分配给任何变量,因此是临时的。 临时对象在表达式的末尾被销毁,因此返回指向QByteArray内部部分的指针的方法data()已经为变量file
分配了一个无效的值,只要';' 被打了。
这样做的安全方法是将结果作为参数直接传递给函数:
readFile(path.toLatin1().data());
我的猜测是你没有重新设置row
的值...因此当你增加行并且它超过ROWS
的值时,你就会停止在tempArray
存储任何新值。 所以你从getline()
读取文件就好了,但是你没有在tempArray中存储这些新值,一旦row >= ROWS
就要验证。
重置row
的值应该可以解决问题。 您也可能希望,根据您的validateData()
函数的工作方式,将其传递给row
而不是ROWS
的值,这样您就不会从前一个循环中获取存储的数据与当前循环中读取的数据混合(如果是getline(inputss, token, ',')
在读取ROWS
数据量之前返回错误并getline(inputss, token, ',')
。
希望这可以帮助,
贾森
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.