无法打开使用流创建的文件
Cannot open file created with ofstream
无法在Ubuntu 11.10上的gedit编辑器中打开.cpp文件。这个文件是用我用C++编写的程序中的一个ofstream对象创建的。程序编译并运行时没有任何错误,之后打开一个文件,逐行读取(将每一行附加到std::string对象),直到到达末尾,然后将字符串返回到main(),然后将其输出到它在硬盘驱动器上创建的单独文件中。然而,当试图在gedit中打开和显示文件时,编辑器只是挂起无论我等待多长时间都不会显示文本,如果我等待太久,当我尝试时要关闭它,它会说它没有回应,我不得不强迫它退出。在nautilus文件浏览器中文件的预览图标中,它显示输出文件只有一行文本,而输入文件当然显示整个页面都充满了文本。事实并非如此,因为输出文件应该包含与输入文件相同的行数,唯一的区别是更改了几行文本。
有人知道是什么原因造成的吗??
请注意,输入文件相当长,包含136871行代码,所以这可能与它有关
以下是创建输出文件的程序代码:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
string fixIssue_SegmentationFault(ifstream& file_handle);
int main() {
cout<< "Thank you for running FixC_html4_tagsIssues.n"
"This little program has been written with the intent of fixingn"
"the issues in the C_html4_tags.h file of the MAW programming project.n"
<< endl
<< "Please hit Enter to fix the detected issues." <<endl;
cin.get();
cout<< "Thank you. Please wait as it fixes the issues..." <<endl;
ifstream C_html4_tags_file_handle("/home/mobilexman/Documents/Programming_Projects/MAW/Modules/core/WebCoder_mod/modules/Html_coder/C_html4_coder/C_html4_elements/C_html4_tags/C_html4_tags.cpp");
string output_str = fixIssue_SegmentationFault(C_html4_tags_file_handle);
C_html4_tags_file_handle.close();
ofstream C_html4_tags_replacement_file_handle("/home/mobilexman/Documents/Programming_Projects/MAW/Modules/core/WebCoder_mod/modules/Html_coder/C_html4_coder/C_html4_elements/C_html4_tags/C_html4_tags_replacement.cpp");
C_html4_tags_replacement_file_handle<< output_str.c_str();
C_html4_tags_replacement_file_handle.close();
cout<< "Congratulations. The issues have been fixed." <<endl;
return 0;
}
string fixIssue_SegmentationFault(ifstream& file_handle) {
//////////////////
//Cause of issue:
/////////////////
///////////////////////////////////////////////////////////////////
//map<S_browser, TYPE_attr_values> attr_supported_attr_values_map;
//...
//TYPE_attr_values& attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
//...
//attr_supported_attr_values.clear();
//attr_supported_attr_values_map.clear();
//...
//attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
/////////////////////////////////////////////////////////////////////////////
//Explanation:
//Inside constructor of C_html4_tags, I created a map for the supported attr values of each Html attribute I created for each Html tag in the constructor.
//The map uses an S_browser object for its key and an object of TYPE_attr_values (which is a typedef of std::vector<S_html_attr_value>) for its mapped value.
//Therefore, I created a TYPE_attr_values& called 'attr_supported_attr_values' to reference the associated mapped value vector of the 'dummy_browser' object,
//which is just a dummy browser object I created so I could create a list of standard Html 4.01 attributes which exist in the specification for now, and later
//create a list of attributes from that list for each browser, according to which attribute values each browser supports (note: this will be done at the
//next level up: C_html4_elements). The code line
////////////////////////////////////////////////////////////////////////////////////////////////
//TYPE_attr_values& attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
///////////////////////////////////////////////////////////////////////////////////////////////
//is where I first create that reference and initialize it to the returned reference of the [] operator of the map, which performs an insert operation if the key passed does not already exist inside the map.
//And the code line
//////////////////////////////////////////////////////////////////////////////
//attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];
/////////////////////////////////////////////////////////////////////////////
//is where I reinitialize (or at least that's what I thought it did when I first wrote the code...) the reference to the returned reference again, for each Html attribute after the first attribute.
//I then attempt to clear after each attribute operations both the referenced vector and then the map before reusing the reference 'attr_supported_attr_values'.
//However, that is what created the segmentation fault. It turns out you cannot use the same reference on more than one object, unlike pointers. So it is invalid to reinitialize that reference
//to point to a new object for each attribute, thus creating the problem. Oddly enough, though, doing this didn't actually produce any compiler errors. It compiles ok, but when attempting to run the program,
//it will return a message saying the program unexpectedly exited when running it normal, and you only get the extra info about the segmentation fault when running the debugger on it. I'm not sure why
//that is, but its probably by design. And so it did take me a bit to figure out why the 'attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];' lines was producing the segmentation
//fault, especially since the attribute it ended on was not actually the second attribute of the first tag, but rather the first attribute of the second tag. I still don't know why that is, but at any rate,
//I believe that after I change the 'attr_supported_attr_values' identifier to a pointer instead of a reference, and adjust all lines using it to treat it as a pointer instead of a reference, the problem
//SHOULD be fixed. But we'll certainly see how it goes...
//////////////////////////
//Steps for fixing issue:
////////////////////////
//1. Read each line of C_html4_tags.cpp until reaching the end, checking each line as we go to see if it contains the target string content. In addition, add the content of each line (regardless of whether it contains the target or not)
//to output_str. Note that the target string content is first "TYPE_attr_values& attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];" which needs to be changed to
//"TYPE_attr_values* attr_supported_attr_values = &attr_supported_attr_values_map[dummy_browser];", and then is the
/////////////////////////////////////
//attr_supported_attr_values.clear();
//attr_supported_attr_values_map.clear();
/////////////////////////////////////////
//lines which needs to be changed to
///////////////////////////////////////
//attr_supported_attr_values->clear();
//attr_supported_attr_values_map->clear();
//////////////////////////////////////////
//2. If the target is found in the current line, perform the necessary changes to the line's content (i.e. buffer_str) before adding it to output_str.
//3. Return output_str.
string output_str;
string buffer_str;
string search_str1 = "TYPE_attr_values& attr_supported_attr_values = attr_supported_attr_values_map[dummy_browser];";
string replacement_str1 = "TYPE_attr_values* attr_supported_attr_values = &attr_supported_attr_values_map[dummy_browser];";
string search_str2 = "attr_supported_attr_values.clear();";
string replacement_str2 = "attr_supported_attr_values->clear();";
string search_str3 = "attr_supported_attr_values_map.clear();";
string replacement_str3 = "attr_supported_attr_values_map->clear();";
size_t pos;
while (getline(file_handle, buffer_str)) {
if (file_handle.good()) { //i.e. no errors while reading lines
if ((pos = buffer_str.find(search_str1, 0)) != string::npos) {
buffer_str.replace(pos, search_str1.size(), replacement_str1);
}
else if ((pos = buffer_str.find(search_str2, 0)) != string::npos) {
buffer_str.replace(pos, search_str2.size(), replacement_str2);
}
else if ((pos = buffer_str.find(search_str3, 0)) != string::npos) {
buffer_str.replace(pos, search_str3.size(), replacement_str3);
}
output_str += buffer_str;
}
}
return output_str;
}
您的问题是getline
提取并丢弃行终止符,这意味着您的输出中最终没有一个换行符。很可能,这会让GEdit非常不高兴(导致你看到的行为),因为它必须计算一个巨大文件的换行。
因此,在构建输出字符串时,应该为每一行添加一个换行符。
相关文章:
- 如何从Windows控制台调用.exe(C++)以在不同的目录(或任何目录)中创建文件夹?
- 避免使用 boost::进程间::消息队列创建文件
- 在C++中创建文件夹选取器对话框的最简单方法是什么?
- 如何在软件代码中使用ofstream创建文件
- 在特定 Unicode 路径中创建文件
- 两个线程一个使用流 Api,另一个线程创建文件失败并出现错误ERROR_SHARING_VIOLATION
- 即使使用 FILE_FLAG_DELETE_ON_CLOSE 属性创建文件,文件也会保留在磁盘上
- C++ 为每个结构{人}条目创建文件
- "Access is Denied" U盘上的创建文件()
- 在c++编程中的文件夹中创建文件
- 创建文件夹结构
- 在C++中创建文件夹
- 创建文件函数是否可以打开仅在WinObj实用程序中的全局目录下列出的设备的句柄?
- 使用 C++ 或 SDL 在 Android 中创建文件
- 如何检测哪些进程更改,重命名或创建文件?
- 如何在 Linux 中通过 C/C++ 以其他用户身份创建文件?
- 挂钩创建文件抛出异常:读取访问冲突
- UWP 创建文件2 ERROR_ACCESS_DENIED "NUL"
- 如何指定创建文件函数获取未缓存的结果?
- Open() 用于创建文件和打开现有文件.有人能分辨出其中的区别