我不知道是否有人会及时看到这个,但我会尝试...... 我在一个介绍性的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
哦,我拿出了
使用namespace std;
因为它给出了:cout是一个模棱两可的错误。
感谢 Ñ
答案 0 :(得分:3)
从哪里开始!!!!
糟糕的做法。每行一个!
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
的代码,现在您处于可能存在危险的情况
因此,存储不无效的指针总是更安全 NOT 。因此,使用它们的唯一安全方法是作为功能的参数。
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());
答案 1 :(得分:1)
我的猜测是你没有重新设置row
的值...因此当你增加行并且它超过ROWS
的值时,你就会停止在tempArray
内存储任何新值{1}}。所以你从getline()
读取文件就好了,但是你没有在tempArray中存储这些新值,只能在row >= ROWS
后验证。
重置row
的值应该可以解决问题。根据您的validateData()
函数的工作原理,您可能还希望将row
的值传递给ROWS
而不是getline(inputss, token, ',')
,这样就不会将上一个循环中存储的数据混入如果ROWS
在您读取{{1}}数据量之前{{1}}返回错误并保释,则会在当前循环中读取数据。
希望这有帮助,
杰森