据我所知,stream.ignore(n,'n')应该忽略(n)个字符或是否达到'\ n',然后跳到下一行,但是,当我运行时下一个代码:
// include...
void insertInfo(int info) {
std::fstream stream("infoFile.txt"); // Open the file
while (!stream.eof()) {
std::string a{};
// getline(stream, a); <--- Tryied this, didn't work neither
stream.ignore(99, '\n');
} // Skip to the last line without any number, in theory
std::cout << info << std::endl; // Check if the output it's correct (Wich is)
stream << info; // Insert the info
stream.close(); // Close the file
}
void main() //Main
{
std::cout << "Enter your name, followed by the info you want to add to infoFile:" << std::endl;
std::string info, temp = "";
std::getline(std::cin, temp); // Get the info input
std::stringstream sstream;
sstream << temp;
sstream >> temp >> info; // Remove the name keeping only the info
temp = ""; // ^
std::string::size_type sz;
insertInfo(stoi(info, &sz)); // Convert info string into an integer and insert it in infoFile
}
控制台会打印出“ info”正确的值,但是,当我检查info.txt时(以前我在其中写了一个“ 0”),则看不到任何更改。 我尝试删除“忽略”功能,它覆盖了0,这正是我要防止的功能。 我也尝试使用“ getline”功能,但是发生了同样的事情。 这是什么错误?
答案 0 :(得分:0)
无法写入文件。
void insertInfo(int info) {
std::fstream stream("infoFile.txt"); // Open the file
使用默认权限打开文件,包括读取。 C ++标准says I should expect "r+"
behaviour和C标准说,必须存在一个以“ r +”行为打开的文件才能被读取(如果有,请添加一个链接)。您无法创建新文件。这是问题1。Asker通过提供文件来解决此问题。
注意:通过相对路径处理文件时要小心。该程序的工作目录可能不在您认为的位置。这是问题1a。看来,问问者目前已经照顾好了。
while (!stream.eof()) {
常见错误。有关更多详细信息,请参见Why is iostream::eof inside a loop condition considered wrong?。在这种情况下,由于您要查找的只是文件的末尾,因此会丢失该文件根本没有打开或遇到任何读取错误的事实。由于处于错误状态的文件永远无法到达文件末尾,因此这很快就变成了无限循环。这是问题2。
std::string a{};
// getline(stream, a); <--- Tryied this, didn't work neither
stream.ignore(99, '\n');
始终测试IO事务是否成功。此呼叫可能会失败,无法选中。
} // Skip to the last line without any number, in theory
假定没有任何问题,并且由于我们没有做所有假设的错误状态检查,因此文件已到达末尾,现在处于EOF错误状态。在我们clear
出现此错误之前,我们无法从流中读取或写入流。这是第3个问题,可能是Asker正在努力解决的问题。
std::cout << info << std::endl; // Check if the output it's correct (Wich is)
stream << info; // Insert the info
这可能会失败而未选中。
stream.close(); // Close the file
这不是必需的。该文件超出范围时将关闭。
}
void insertInfo(int info) {
std::fstream stream("infoFile.txt"); // Open the file
while (!stream.eof()) {
stream.ignore(99, '\n');
} // Skip to the last line without any number, in theory
std::cout << info << std::endl; // Check if the output it's correct (Wich is)
stream.clear(); // Added a call to clear the error flags.
stream << info; // Insert the info
stream.close(); // Close the file
}
现在我们可以写入文件了。但是让我们改善一下吧?
void insertInfo(int info) {
std::fstream stream("infoFile.txt");
while (stream.ignore(99, '\n')) // moved ignore here. now we ignore, then test the result
{
}
stream.clear();
stream << info << '\n'; // added a line ending. Without some delimiter the file
// turns into one big number
}
请注意,这并非完全符合犹太标准。如果任何忽略由于某种原因而失败,我们将退出紧急状态并可能覆盖数据,因为代码会盲目地clear
进行写入。我不会在这里花费很多时间来尝试对此进行修补,因为我们可以非常简单地解决同时创建不存在文件的问题。
void insertInfo(int info) {
std::fstream stream("infoFile.txt", std::ios::app);
stream << info << '\n';
}
两行,差不多完成了。使用app
,我们将附加到文件中。我们不需要查找文件的末尾,流会自动指向它。如果该文件不存在,则会创建它。
下一个改进:让人们知道写入是否失败。
bool insertInfo(int info) {
std::fstream stream("infoFile.txt", std::ios::app);
return static_cast<bool>(stream << info << '\n');
}
如果由于某种原因未写入文件,则该函数将返回false,并且调用者可以弄清楚该怎么做。剩下的唯一一件事就是加强流程。由于我们所做的只是写给ti,因此我们不需要fstream
的宽容。始终从限制性最高的位置开始,并移至最小的位置。这样可以避免可能的错误,从而避免发生这些错误。
bool insertInfo(int info) {
std::ofstream stream("infoFile.txt", std::ios::app);
return static_cast<bool>(stream << info << '\n');
}
现在,我们使用ofstream
并消除了在不读取流时读取流的能力带来的所有额外开销和风险。