1我目前正在做一个项目,创建我自己的游戏在OpenGL。 我现在的问题是,如果我读取一个文件,由于std::ifstream解构器(更具体地在“std::basic_ifstream
”中)中的某些内容,我读取该文件的函数会产生一个SIGABRT。 这个功能以前对我有用,但是突然停止工作了。
我的目标很简单:一个将文件读取到字符*的可靠实现。 多线程目前不是我关心的问题。
下面是我对文件读取功能的实现。 它接受一个路径,并应将该路径处的文件内容写入out
参数中。
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#include <cassert>
#include "Utility.h"
char * Utility::readFile(const char* path,char*& out){
#ifndef NDEBUG
std::cout<<"Getting file: "<<path<<"\n";
#endif
// Open the file, but freak out if not valid.
std::ifstream file=std::ifstream(path);
assert(file.good());
if(!file.good())
{
throw std::runtime_error((std::string)"Couldn't open file for loading: "+path);
}
// Read the file contents into a char buffer.
std::stringstream buffer;buffer << file.rdbuf();
std::string fileContentsStr = buffer.str();
out = new char[fileContentsStr.size()];
strcpy(out,fileContentsStr.c_str());
return out;
}
我的代码位于C0D3-M4513R/OpenGGAME。 我已经尝试了一个最小的示例,它工作并使用相同的编译标志(链接器标志除外)。 test.txt和test1.txt只是包含一些在我的键盘上随机黑客生成的垃圾文本。
#include <cassert>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
//This Function is the same as the one above!!!
char *readFile(const char *path, char *&out) {
#ifndef NDEBUG
std::cout << "Getting file: " << path << "\n";
#endif
// Open the file, but freak out if not valid.
std::ifstream file = std::ifstream(path);
assert(file.good());
if (!file.good()) {
throw std::runtime_error((std::string) "Couldn't open file for loading: " + path);
}
// Read the file contents into a char buffer.
std::stringstream buffer;
buffer << file.rdbuf();
//convert the stringstream to a string
std::string fileContentsStr = buffer.str();
//copy the contents of the string to a char array
out = new char[fileContentsStr.size()];
strcpy(out, fileContentsStr.c_str());
//return char array address (which should be the same as the start?)
return out;
}
int main() {
//The programm started!
std::cout << "Hello, World!" << std::endl;
//Define a space for the contents of the file to live
char *out;
//Read the contents of a file
out = readFile("test.txt", out);
//Print contents of the file
std::cout << out << std::endl;
char *out1;
//Read the contents of a file
out1 = readFile("test1.txt", out1);
//Print contents of the file
std::cout << out1 << std::endl;
return 0;
}
strcpy
:
将src指向的字符串(包括空终止符)复制到dest指向的第一个元素的字符数组。 如果目标数组不够大,则行为未定义。 如果字符串重叠,则行为未定义。
C_str
:
返回指向空终止字符数组的指针,该数组的数据与存储在字符串中的数据等效。
out = new char[fileContentsStr.size()];
strcpy(out,fileContentsStr.c_str());
在将std::string
与C字符串混合使用时需要小心,因为std::string
不是空终止的,并且不计算nullterminator的大小。 但是,c_str
确实返回一个指向空终止字符数组的指针。
您要求strcpy
将FileContentsStr.size()+1
(大小+空终止符)写入只有FileContentsStr.size()
元素的字符数组中。
PS:正如在一个注释中提到的,您应该考虑返回一个std::string
。 您使用的是一个原始的拥有指针,这是容易出错的,应该避免。 要么使用智能指针,要么让std::string
管理char-array(这就是它的实际用途)。