结果与 fstream::read 不一致



我的程序使用一个小的SQLite3数据库。为了确保它在程序启动时确实存在,我在执行的文件中有一个数据库创建脚本。

脚本工作没有问题。

但是,当使用 C++ I/O 函数从该文件读取时,我经常在文件末尾收到无效字符,这导致脚本包含错误并且无法由 SQLite 库正确执行。下面是显示缓冲区内容时的示例: // Proper content from the file, then a random character is there 1 Error executing request: near "1": syntax error

其他字符也会出现,空格,数字,字母... 这是我加载脚本的代码:

std::cerr << "Creating database if needed...n";
char sql_script[] = "/path/to/script.sql";
int script_length;
bool result = false;
std::ifstream script_fs(sql_script, std::fstream::binary | std::fstream::in);
if (script_fs) {
char* buffer;
char** err_msg = NULL;
script_fs.seekg(0, script_fs.end);
script_length = script_fs.tellg();
script_fs.seekg(0, script_fs.beg);
buffer = new char[script_length];
script_fs.read(buffer, script_length);
std::cout << "sql:n" << buffer << "n";
if (sqlite3_exec(m_db, buffer, NULL, NULL, err_msg) == SQLITE_OK){
result = true;
} else {
std::cerr << "Error executing: " << sqlite3_errmsg(m_db) << "n" << err_msg << "n";
}
delete buffer;
script_fs.close();
} else {
std::cerr << "Error opening script: " << strerror(errno) << "n";
}
return result;
}

为什么会发生这种情况,我该如何解决这个问题?

您需要确保有一个以 null 结尾的字符串。

  1. 为另外一个字符分配内存。
  2. 将空字符分配给buffer的最后一个元素。

buffer = new char[script_length+1];
script_fs.read(buffer, script_length);
buffer[script_length] = '';

此外,使用delete的数组形式。

delete [] buffer;

不要混合使用 C 和 C++,如果您想使用 ifstream 读取 C++ 中的 sql 查询文件,那么下面的代码 C++ 可以是一种不需要管理内存的方法,需要处理诸如分配一个额外的 '\0' 字符等事情:

#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main() {
ifstream fin("test.sql", std::fstream::binary | std::fstream::in);
std::string sqlquery = std::string(std::istreambuf_iterator<char>(fin), std::istreambuf_iterator<char>());
std::cout<<sqlquery<<std::endl;
return 0;
}

最新更新