您好,很抱歉,答案是否明确。我对编程还是很陌生,需要一些指导。
此函数应该只将它接收到的三个字符串参数之一写入我已经生成的txt文件中。当我运行程序时,该功能似乎正常运行,并且cout语句显示信息在字符串中,并且确实成功通过了。问题是运行程序后,我去检查txt文件,发现它仍然是空白。
我正在Visual Studio Professional 2015上使用C ++ 17。
void AddNewMagicItem(const std::string & ItemKey,
const std::string & ItemDescription,
const std::string &filename)
{
const char* ItemKeyName = ItemKey.c_str();
const char* ItemDescriptionBody = ItemDescription.c_str();
const char* FileToAddItemTo = filename.c_str();
std::ofstream AddingItem(FileToAddItemTo);
std::ifstream FileCheck(FileToAddItemTo);
AddingItem.open(FileToAddItemTo, std::ios::out | std::ios::app);
if (_access(FileToAddItemTo, 0) == 0)
{
if (FileCheck.is_open())
{
AddingItem << ItemKey;
std::cout << ItemKey << std::endl;
}
}
AddingItem.close(); // not sure these are necessary
FileCheck.close(); //not sure these are necessary
}
当您将字符串传递给ItemKey参数时,这应该在.txt文件上打印一条消息。
非常感谢您的帮助,请原谅我,因为我也是stackoverflow的新手,在格式化此问题时可能会犯一些错误或不够清楚。
添加:谢谢所有回答此问题的人以及您的所有帮助。我感谢您的帮助,并衷心感谢大家对这个主题的帮助,评论和意见。愿您的代码每次都能编译,并且您的代码评论总是会被注释。
答案 0 :(得分:1)
std::ofstream AddingItem(FileToAddItemTo);
打开文件。用
再次打开AddingItem.open(FileToAddItemTo, std::ios::out | std::ios::app);
导致流失败。
将打开模式移动到构造函数(std::ofstream AddingItem(FileToAddItemTo, std::ios::app);
)中,然后删除手动打开。
请注意,仅需要app
打开模式。 ofstream
表示out
模式已设置。
注意:如果用户无权访问该文件,则无法打开该文件。无需对此进行单独测试。我发现先测试打开的文件,然后再调用perror
或类似的针对特定目标的调用,以提供有关失败原因的详细信息,这是有用的功能。
请注意,流中可能有多个different states,is_open
有点偏。您想检查所有这些,以确保IO事务成功。在这种情况下,文件已打开,因此如果只检查is_open
,则会错过failbit
。读取时一个常见的相关错误仅是测试EOF并以失败的读取循环结束,该读取将永远不会到达文件末尾(or reading past the end of the file by checking too soon)。
AddingItem << ItemKey;
成为
if (!(AddingItem << ItemKey))
{
//handle failure
}
有时,您将需要更好的粒度来确定确切发生了什么,以便正确处理错误。检查状态位,并检查perror
和特定于目标的状态
诊断如上。
不建议同时打开多个fstreams
进行读写的文件。不同的流将为同一文件提供不同的缓冲视图,从而导致不稳定。
可以尝试通过单个ostream
读取和写入相同的文件,但是很难正确地完成。经验法则是将文件读入内存,然后关闭文件,编辑内存,然后打开文件,写入内存,然后关闭文件。如果可能的话,请保留文件的内存副本,这样就不必重新读取文件。
如果需要确定已正确写入文件,请先写入文件,然后将其读回,解析并确认信息正确。验证时,不允许再次写入文件。不要尝试对此进行多线程处理。
这是一个小例子,用来说明哪里出了问题以及哪里出了错。
#include <iostream>
#include <fstream>
int main()
{
std::ofstream AddingItem("test");
if (AddingItem.is_open()) // test file is open
{
std::cout << "open";
}
if (AddingItem) // test stream is writable
{
std::cout << " and writable\n";
}
else
{
std::cout << " and NOT writable\n";
}
AddingItem.open("test", std::ios::app);
if (AddingItem.is_open())
{
std::cout << "open";
}
if (AddingItem)
{
std::cout << " and writable\n";
}
else
{
std::cout << " and NOT writable\n";
}
}
假设工作目录有效,并且用户具有编写测试的权限,我们将看到程序输出为
open and writable
open and NOT writable
这表明
std::ofstream AddingItem("test");
打开文件,然后
AddingItem.open("test", std::ios::app);
使文件保持打开状态,但将流置于不可写的错误状态,以迫使您处理试图同时在同一流中打开两个文件的潜在逻辑错误。基本上是说:“对不起戴夫,我恐怕不能这样做。”没有Undefined Behaviour或没有完整的Hal 9000血洗。
不幸的是,要获取此消息,您必须查看正确的错误位。在这种情况下,我用if (AddingItem)
查看了所有这些内容。
答案 1 :(得分:0)
作为已经给出的问题评论的补充:
如果要将数据写入文件,我不明白为什么要使用std::ifstream
。只需std::ofstream
。
您可以通过以下方式将数据写入文件:
const std::string file_path("../tmp_test/file_test.txt"); // path to the file
std::string content_to_write("Something\n"); // content to be written in the file
std::ofstream file_s(file_path, std::ios::app); // construct and open the ostream in appending mode
if(file_s) // if the stream is successfully open
{
file_s << content_to_write; // write data
file_s.close(); // close the file (or you can also let the file_s destructor do it for you at the end of the block)
}
else
std::cout << "Fail to open: " << file_path << std::endl; // write an error message
正如您所说的对编程来说还很陌生,我已经明确评论了每一行,以使其更易于理解。
希望对您有帮助。
编辑:
有关更多说明,您尝试打开3次文件(在写入模式下两次,在读取模式下两次)。这是导致您出现问题的原因。您只需在写入模式下打开一次文件即可。
此外,检查输入流是否打开也不会告诉您输出流是否也打开。请记住,您打开了一个文件流。如果要检查它是否正确打开,则必须通过相关对象而不是另一个对象进行检查。