read more files using only one std::ifstream file

修复C++文件读取Bug
本文介绍了一个使用C++标准库ifstream连续读取多个文件时遇到的问题及解决方法。当使用同一个ifstream对象读取多个文件时,若不正确地重置ifstream的状态,会导致后续文件无法正常读取。文章提供了具体的代码示例并详细解释了如何通过关闭并清除ifstream对象的状态来解决此问题。

Today meets a bug, when read more than one files using only one std::ifstream object. possible code as following:

std::ifstream infile

infile.open(a)
if (infile.bad()) {
   std::cerr << "read failed" << std::endl;  
}

std::string line = "";
while (std::getline(infile, line), infile.good()) {
   std::cout << line << std::endl;
}

infile.close();

//next ,continue read b file
infile.open(b);

if (infile.bad()) {
  std::cerr << "read failed" << std::endl;
}
line = "";
while (std::getline(infile, line), infile.good()) {
   std::cout << line << std::endl;
}

but, file b can not be read out!

OK, the bug is :after read out of file a, the object "infile"'s state is error, because of reading nothing out finally for file a.

only use "infile.close()" is not enough, it also needs clear; so ,fix it as follows:

infile.close()
infile.clear();

then bug fixed.

reminding~

转载于:https://www.cnblogs.com/crafet/archive/2013/01/28/2880603.html

#include <iostream> #include <fstream> #include <vector> #include <map> #include <algorithm> #include <functional> #include <cctype> #include <memory> #include <variant> #include <regex> #include <cmath> #include <unordered_map> #include <locale> #include <iomanip> #include <sstream> #ifdef _WIN32 #include <windows.h> #include <io.h> #include <fcntl.h> #endif // 基础类型定义 using Value = std::variant<int, double, std::string, bool>; using Row = std::vector<Value>; using Table = std::vector<Row>; using ColumnMap = std::unordered_map<std::string, int>; // 字符串处理函数 std::string trim(const std::string& str) { // 去除字符串两端的空白字符 size_t first = str.find_first_not_of(" \t\n\r\f\v"); if (first == std::string::npos) return ""; size_t last = str.find_last_not_of(" \t\n\r\f\v"); return str.substr(first, (last - first + 1)); } // 改进的DBF编码转换函数 std::string convertDBFToUTF8(const std::string& str) { #ifdef _WIN32 if (str.empty()) return str; // 尝试从GBK转换为UTF-8 int len = MultiByteToWideChar(936, 0, str.c_str(), -1, NULL, 0); if (len > 0) { wchar_t* wstr = new wchar_t[len]; MultiByteToWideChar(936, 0, str.c_str(), -1, wstr, len); len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); if (len > 0) { char* utf8Str = new char[len]; WideCharToMultiByte(CP_UTF8, 0, wstr, -1, utf8Str, len, NULL, NULL); std::string result(utf8Str); delete[] wstr; delete[] utf8Str; return result; } delete[] wstr; } return str; #else return str; // 非Windows平台直接返回 #endif } // 用于处理DBF字段名的函数 std::string processDBFFieldName(const char* name, size_t len) { std::string fieldName(name, len); fieldName = fieldName.substr(0, fieldName.find('\0')); fieldName = trim(fieldName); fieldName = convertDBFToUTF8(fieldName); return fieldName; } // 用于处理DBF字符串字段的函数 std::string processDBFString(const char* str, size_t len) { std::string result(str, len); result = trim(result); result = convertDBFToUTF8(result); return result; } struct FieldDescriptor { char name[11]; char type; uint32_t address; uint8_t length; uint8_t decimal; }; struct DBFHeader { uint8_t version; uint8_t last_update[3]; uint32_t num_records; uint16_t header_size; uint16_t record_size; }; // DBF 文件读取器 class DBFReader { public: DBFReader(const std::string& filename) : filename(filename) {} bool read() { std::ifstream file(filename, std::ios::binary); if (!file) return false; // 读取文件头 file.read(reinterpret_cast<char*>(&header), sizeof(DBFHeader)); // 读取字段描述 int num_fields = (header.header_size - sizeof(DBFHeader) - 1) / 32; for (int i = 0; i < num_fields; ++i) { FieldDescriptor fd; file.read(reinterpret_cast<char*>(&fd), sizeof(FieldDescriptor)); fields.push_back(fd); // 处理字段名 std::string fieldName = processDBFFieldName(fd.name, sizeof(fd.name)); columnMap[fieldName] = i; } // 跳过文件头结束符 file.seekg(header.header_size); // 读取记录 for (int i = 0; i < header.num_records; ++i) { char delete_flag; file.read(&delete_flag, 1); if (delete_flag == '*') { file.seekg(header.record_size - 1, std::ios::cur); continue; // 跳过已删除记录 } Row row; for (size_t j = 0; j < fields.size(); j++) { const auto& field = fields[j]; char* buffer = new char[field.length + 1]; file.read(buffer, field.length); buffer[field.length] = '\0'; // 转换数据类型 Value value; switch (field.type) { case 'N': // 数值 case 'I': // 整数 case 'F': // 浮点数 { std::string numStr = trim(std::string(buffer)); if (numStr.empty()) { if (field.type == 'I') { value = 0; // 整数默认值 } else { value = 0.0; // 浮点数默认值 } } else if (field.decimal > 0 || numStr.find('.') != std::string::npos) { try { value = std::stod(numStr); } catch (...) { value = 0.0; } } else { try { value = std::stoi(numStr); } catch (...) { value = 0; } } } break; case 'D': // 日期 (格式: YYYYMMDD) { std::string dateStr(buffer); if (dateStr.length() == 8 && std::all_of(dateStr.begin(), dateStr.end(), ::isdigit)) { value = dateStr.substr(0, 4) + "-" + dateStr.substr(4, 2) + "-" + dateStr.substr(6, 2); } else { value = dateStr; } } break; case 'L': // 逻辑 { char c = std::toupper(buffer[0]); value = (c == 'T' || c == 'Y' || c == '1'); } break; case 'C': // 字符 case 'M': // 备注 default: { // 处理字符串字段 std::string str = processDBFString(buffer, field.length); value = str; } break; } row.push_back(value); delete[] buffer; } data.push_back(row); } return true; } const Table& getData() const { return data; } const std::vector<FieldDescriptor>& getFields() const { return fields; } const ColumnMap& getColumnMap() const { return columnMap; } private: std::string parseDate(const char* buffer) { // 简单日期转换: YYYYMMDD -> YYYY-MM-DD std::string date(buffer); if (date.length() == 8 && std::all_of(date.begin(), date.end(), ::isdigit)) { return date.substr(0, 4) + "-" + date.substr(4, 2) + "-" + date.substr(6, 2); } return date; } std::string filename; DBFHeader header; std::vector<FieldDescriptor> fields; Table data; ColumnMap columnMap; }; // SQL 查询解析器 class SQLParser { public: enum TokenType { SELECT, FROM, WHERE, INSERT, INTO, VALUES, UPDATE, SET, DELETE_TOKEN, AND, OR, NOT, EQ, NEQ, LT, GT, LTE, GTE, COMMA, LPAREN, RPAREN, IDENTIFIER, STRING, NUMBER, BOOL, STAR, EOF_TOKEN }; struct Token { TokenType type; std::string value; // 添加构造函数以支持初始化列表 Token(TokenType t) : type(t) {} Token(TokenType t, const std::string& v) : type(t), value(v) {} }; explicit SQLParser(const std::string& sql) : sql(sql), pos(0) {} std::vector<Token> tokenize() { std::vector<Token> tokens; while (pos < sql.size()) { char c = sql[pos]; if (std::isspace(c)) { pos++; continue; } // 处理标识符和关键字 if (std::isalpha(c) || c == '_') { std::string ident; while (pos < sql.size() && (std::isalnum(sql[pos]) || sql[pos] == '_')) { ident += sql[pos++]; } std::transform(ident.begin(), ident.end(), ident.begin(), ::toupper); if (ident == "SELECT") tokens.push_back(Token(SELECT)); else if (ident == "FROM") tokens.push_back(Token(FROM)); else if (ident == "WHERE") tokens.push_back(Token(WHERE)); else if (ident == "INSERT") tokens.push_back(Token(INSERT)); else if (ident == "INTO") tokens.push_back(Token(INTO)); else if (ident == "VALUES") tokens.push_back(Token(VALUES)); else if (ident == "UPDATE") tokens.push_back(Token(UPDATE)); else if (ident == "SET") tokens.push_back(Token(SET)); else if (ident == "DELETE") tokens.push_back(Token(DELETE_TOKEN)); else if (ident == "AND") tokens.push_back(Token(AND)); else if (ident == "OR") tokens.push_back(Token(OR)); else if (ident == "NOT") tokens.push_back(Token(NOT)); else if (ident == "TRUE" || ident == "FALSE") { tokens.push_back(Token(BOOL, ident)); } else { tokens.push_back(Token(IDENTIFIER, ident)); } continue; } // 处理数字 if (std::isdigit(c) || c == '.') { std::string num; bool hasDecimal = false; while (pos < sql.size() && (std::isdigit(sql[pos]) || sql[pos] == '.')) { if (sql[pos] == '.') { if (hasDecimal) break; hasDecimal = true; } num += sql[pos++]; } tokens.push_back(Token(NUMBER, num)); continue; } // 处理字符串 if (c == '\'') { pos++; std::string str; while (pos < sql.size() && sql[pos] != '\'') { if (sql[pos] == '\\' && pos + 1 < sql.size()) { pos++; switch (sql[pos]) { case 'n': str += '\n'; break; case 't': str += '\t'; break; case 'r': str += '\r'; break; default: str += sql[pos]; break; } } else { str += sql[pos]; } pos++; } if (pos < sql.size() && sql[pos] == '\'') pos++; tokens.push_back(Token(STRING, str)); continue; } // 处理操作符 switch (c) { case '*': tokens.push_back(Token(STAR)); break; case ',': tokens.push_back(Token(COMMA)); break; case '(': tokens.push_back(Token(LPAREN)); break; case ')': tokens.push_back(Token(RPAREN)); break; case '=': tokens.push_back(Token(EQ)); break; case '<': if (pos + 1 < sql.size() && sql[pos + 1] == '>') { tokens.push_back(Token(NEQ)); pos++; } else if (pos + 1 < sql.size() && sql[pos + 1] == '=') { tokens.push_back(Token(LTE)); pos++; } else { tokens.push_back(Token(LT)); } break; case '>': if (pos + 1 < sql.size() && sql[pos + 1] == '=') { tokens.push_back(Token(GTE)); pos++; } else { tokens.push_back(Token(GT)); } break; case '!': if (pos + 1 < sql.size() && sql[pos + 1] == '=') { tokens.push_back(Token(NEQ)); pos++; } break; } pos++; } tokens.push_back(Token(EOF_TOKEN)); return tokens; } private: std::string sql; size_t pos; }; // SQL 查询执行引擎 class SQLExecutor { public: SQLExecutor(DBFReader& reader) : reader(reader) {} Table execute(const std::string& sql) { SQLParser parser(sql); auto tokens = parser.tokenize(); if (tokens.empty()) return {}; switch (tokens[0].type) { case SQLParser::SELECT: return executeSelect(tokens); case SQLParser::INSERT: return executeInsert(tokens); case SQLParser::UPDATE: return executeUpdate(tokens); case SQLParser::DELETE_TOKEN: return executeDelete(tokens); default: std::cerr << "Unsupported SQL statement" << std::endl; return {}; } } private: // SELECT 查询执行 Table executeSelect(const std::vector<SQLParser::Token>& tokens) { Table result; auto& data = reader.getData(); auto& fields = reader.getFields(); auto& columnMap = reader.getColumnMap(); // 解析字段列表 std::vector<std::string> selectedColumns; size_t pos = 1; // 跳过SELECT if (pos < tokens.size() && tokens[pos].type == SQLParser::STAR) { for (const auto& field : fields) { std::string fieldName = processDBFFieldName(field.name, sizeof(field.name)); selectedColumns.push_back(fieldName); } pos += 2; // 跳过 * 和 FROM } else { while (pos < tokens.size() && tokens[pos].type != SQLParser::FROM) { if (tokens[pos].type == SQLParser::IDENTIFIER) { selectedColumns.push_back(tokens[pos].value); } pos++; } if (pos < tokens.size()) pos++; // 跳过FROM } // 解析表名 (忽略,因为只有一个表) if (pos < tokens.size() && tokens[pos].type == SQLParser::IDENTIFIER) { std::string tableName = tokens[pos].value; pos++; } // 解析WHERE条件 std::function<bool(const Row&)> condition = [](const Row&) { return true; }; if (pos < tokens.size() && tokens[pos].type == SQLParser::WHERE) { pos++; condition = parseCondition(tokens, pos, columnMap); } // 执行查询 for (const auto& row : data) { if (condition(row)) { Row resultRow; for (const auto& col : selectedColumns) { // 尝试直接匹配 auto it = columnMap.find(col); if (it != columnMap.end()) { resultRow.push_back(row[it->second]); } else { // 如果直接匹配失败,尝试其他可能的编码格式 bool found = false; for (const auto& pair : columnMap) { // 比较去除空格后的字段名 std::string mapKey = pair.first; std::string reqKey = col; // 去除空格 mapKey.erase(std::remove(mapKey.begin(), mapKey.end(), ' '), mapKey.end()); reqKey.erase(std::remove(reqKey.begin(), reqKey.end(), ' '), reqKey.end()); if (mapKey == reqKey) { resultRow.push_back(row[pair.second]); found = true; break; } } if (!found) { resultRow.push_back(std::string("")); } } } result.push_back(resultRow); } } return result; } // INSERT 语句执行 Table executeInsert(const std::vector<SQLParser::Token>& tokens) { size_t pos = 1; // 跳过INSERT if (tokens[pos].type != SQLParser::INTO) { std::cerr << "Expected INTO after INSERT" << std::endl; return {}; } pos++; // 跳过INTO if (tokens[pos].type != SQLParser::IDENTIFIER) { std::cerr << "Expected table name after INTO" << std::endl; return {}; } std::string tableName = tokens[pos++].value; if (tokens[pos].type != SQLParser::LPAREN) { std::cerr << "Expected '(' after table name" << std::endl; return {}; } pos++; // 跳过'(' // 解析列名 std::vector<std::string> columns; while (pos < tokens.size() && tokens[pos].type != SQLParser::RPAREN) { if (tokens[pos].type == SQLParser::IDENTIFIER) { columns.push_back(tokens[pos].value); } pos++; if (tokens[pos].type == SQLParser::COMMA) pos++; } pos++; // 跳过')' if (tokens[pos].type != SQLParser::VALUES) { std::cerr << "Expected VALUES after column list" << std::endl; return {}; } pos++; // 跳过VALUES if (tokens[pos].type != SQLParser::LPAREN) { std::cerr << "Expected '(' after VALUES" << std::endl; return {}; } pos++; // 跳过'(' // 解析值 Row newRow; while (pos < tokens.size() && tokens[pos].type != SQLParser::RPAREN) { if (tokens[pos].type == SQLParser::STRING) { newRow.push_back(tokens[pos].value); } else if (tokens[pos].type == SQLParser::NUMBER) { if (tokens[pos].value.find('.') != std::string::npos) { newRow.push_back(std::stod(tokens[pos].value)); } else { newRow.push_back(std::stoi(tokens[pos].value)); } } else if (tokens[pos].type == SQLParser::BOOL) { newRow.push_back((tokens[pos].value == "TRUE")); } else if (tokens[pos].type == SQLParser::IDENTIFIER) { // 假设为列名或其他不支持的类型,暂不处理 newRow.push_back(tokens[pos].value); } pos++; if (tokens[pos].type == SQLParser::COMMA) pos++; } pos++; // 跳过')' // 验证列数与值数一致 if (columns.size() != newRow.size()) { std::cerr << "Column count does not match value count" << std::endl; return {}; } // 获取列映射 const auto& columnMap = reader.getColumnMap(); const auto& fields = reader.getFields(); // 构造完整行数据,按字段顺序填充 Row fullRow(fields.size()); for (size_t i = 0; i < columns.size(); ++i) { auto it = columnMap.find(columns[i]); if (it == columnMap.end()) { std::cerr << "Unknown column: " << columns[i] << std::endl; return {}; } fullRow[it->second] = newRow[i]; } // 添加新行到数据表 const_cast<Table&>(reader.getData()).push_back(fullRow); // 返回新插入的行 Table result; result.push_back(fullRow); return result; } // UPDATE 语句执行 Table executeUpdate(const std::vector<SQLParser::Token>& tokens) { size_t pos = 1; // 跳过UPDATE if (tokens[pos].type != SQLParser::IDENTIFIER) { std::cerr << "Expected table name after UPDATE" << std::endl; return {}; } std::string tableName = tokens[pos++].value; if (tokens[pos].type != SQLParser::SET) { std::cerr << "Expected SET after table name in UPDATE" << std::endl; return {}; } pos++; // 跳过SET // 解析更新字段 std::vector<std::pair<std::string, Value>> updates; while (pos < tokens.size() && tokens[pos].type == SQLParser::IDENTIFIER) { std::string colName = tokens[pos++].value; if (pos < tokens.size() && tokens[pos].type == SQLParser::EQ) { pos++; // 跳过= Value value; if (tokens[pos].type == SQLParser::STRING) { value = tokens[pos].value; } else if (tokens[pos].type == SQLParser::NUMBER) { if (tokens[pos].value.find('.') != std::string::npos) { value = std::stod(tokens[pos].value); } else { value = std::stoi(tokens[pos].value); } } else if (tokens[pos].type == SQLParser::BOOL) { value = (tokens[pos].value == "TRUE"); } pos++; // 跳过值 updates.push_back({colName, value}); } if (pos < tokens.size() && tokens[pos].type == SQLParser::COMMA) { pos++; // 跳过逗号 } } // 解析WHERE条件 std::function<bool(const Row&)> condition = [](const Row&) { return true; }; if (pos < tokens.size() && tokens[pos].type == SQLParser::WHERE) { pos++; condition = parseCondition(tokens, pos, reader.getColumnMap()); } // 执行更新 auto& data = const_cast<Table&>(reader.getData()); // 移除const const auto& columnMap = reader.getColumnMap(); Table updatedRows; for (auto& row : data) { if (condition(row)) { // 该行满足更新条件 for (const auto& [colName, value] : updates) { auto it = columnMap.find(colName); if (it != columnMap.end()) { row[it->second] = value; } } updatedRows.push_back(row); } } return updatedRows; } // DELETE 语句执行 Table executeDelete(const std::vector<SQLParser::Token>& tokens) { // 实现删除逻辑 std::cout << "DELETE operation executed" << std::endl; return {}; } public: // 解析WHERE条件 std::function<bool(const Row&)> parseCondition( const std::vector<SQLParser::Token>& tokens, size_t& pos, const ColumnMap& columnMap) { // 递归解析条件表达式 return parseExpression(tokens, pos, columnMap); } std::function<bool(const Row&)> parseExpression( const std::vector<SQLParser::Token>& tokens, size_t& pos, const ColumnMap& columnMap) { auto left = parseTerm(tokens, pos, columnMap); while (pos < tokens.size()) { if (tokens[pos].type == SQLParser::AND) { pos++; auto right = parseTerm(tokens, pos, columnMap); return [=](const Row& row) { return left(row) && right(row); }; } else if (tokens[pos].type == SQLParser::OR) { pos++; auto right = parseTerm(tokens, pos, columnMap); return [=](const Row& row) { return left(row) || right(row); }; } else { break; } } return left; } std::function<bool(const Row&)> parseTerm( const std::vector<SQLParser::Token>& tokens, size_t& pos, const ColumnMap& columnMap) { if (tokens[pos].type == SQLParser::LPAREN) { pos++; auto expr = parseExpression(tokens, pos, columnMap); if (tokens[pos].type == SQLParser::RPAREN) pos++; return expr; } if (tokens[pos].type == SQLParser::NOT) { pos++; auto expr = parseTerm(tokens, pos, columnMap); return [=](const Row& row) { return !expr(row); }; } return parseComparison(tokens, pos, columnMap); } std::function<bool(const Row&)> parseComparison( const std::vector<SQLParser::Token>& tokens, size_t& pos, const ColumnMap& columnMap) { if (pos >= tokens.size()) return [](const Row&) { return false; }; std::string colName = tokens[pos].value; pos++; if (pos >= tokens.size()) return [](const Row&) { return false; }; SQLParser::TokenType op = tokens[pos].type; pos++; if (pos >= tokens.size()) return [](const Row&) { return false; }; Value value; if (tokens[pos].type == SQLParser::STRING) { value = tokens[pos].value; } else if (tokens[pos].type == SQLParser::NUMBER) { if (tokens[pos].value.find('.') != std::string::npos) { value = std::stod(tokens[pos].value); } else { value = std::stoi(tokens[pos].value); } } else if (tokens[pos].type == SQLParser::BOOL) { value = (tokens[pos].value == "TRUE"); } pos++; // 查找字段索引 int colIndex = -1; auto it = columnMap.find(colName); if (it != columnMap.end()) { colIndex = it->second; } else { // 如果直接查找失败,尝试其他匹配方式 for (const auto& pair : columnMap) { std::string mapKey = pair.first; std::string reqKey = colName; // 去除空格后比较 mapKey.erase(std::remove(mapKey.begin(), mapKey.end(), ' '), mapKey.end()); reqKey.erase(std::remove(reqKey.begin(), reqKey.end(), ' '), reqKey.end()); if (mapKey == reqKey) { colIndex = pair.second; break; } } } if (colIndex == -1) { return [](const Row&) { return false; }; } switch (op) { case SQLParser::EQ: return [=](const Row& row) { return row[colIndex] == value; }; case SQLParser::NEQ: return [=](const Row& row) { return row[colIndex] != value; }; case SQLParser::LT: return [=](const Row& row) { return compareValues(row[colIndex], value) < 0; }; case SQLParser::GT: return [=](const Row& row) { return compareValues(row[colIndex], value) > 0; }; case SQLParser::LTE: return [=](const Row& row) { return compareValues(row[colIndex], value) <= 0; }; case SQLParser::GTE: return [=](const Row& row) { return compareValues(row[colIndex], value) >= 0; }; default: return [](const Row&) { return false; }; } } int compareValues(const Value& a, const Value& b) { if (a.index() != b.index()) { // 尝试转换为相同类型 if (std::holds_alternative<int>(a) && std::holds_alternative<double>(b)) { return compareValues(Value(static_cast<double>(std::get<0>(a))), b); } if (std::holds_alternative<double>(a) && std::holds_alternative<int>(b)) { return compareValues(a, Value(static_cast<double>(std::get<0>(b)))); } return 0; // 不同类型无法比较 } switch (a.index()) { case 0: // int return (std::get<0>(a) == std::get<0>(b)) ? 0 : (std::get<0>(a) < std::get<0>(b)) ? -1 : 1; case 1: // double return (std::get<1>(a) == std::get<1>(b)) ? 0 : (std::get<1>(a) < std::get<1>(b)) ? -1 : 1; case 2: // string return std::get<2>(a).compare(std::get<2>(b)); case 3: // bool return static_cast<int>(std::get<3>(a)) - static_cast<int>(std::get<3>(b)); default: return 0; } } DBFReader& reader; }; // 结果打印函数 void printTable(const Table& table, const std::vector<std::string>& headers) { // 计算列宽 std::vector<size_t> widths(headers.size(), 0); for (size_t i = 0; i < headers.size(); i++) { widths[i] = headers[i].size(); } for (const auto& row : table) { for (size_t i = 0; i < row.size(); i++) { size_t len = 0; std::visit([&](const auto& arg) { using T = std::decay_t<decltype(arg)>; if constexpr (std::is_same_v<T, std::string>) { len = arg.size(); } else if constexpr (std::is_same_v<T, int> || std::is_same_v<T, double>) { std::ostringstream oss; oss << arg; len = oss.str().size(); } else if constexpr (std::is_same_v<T, bool>) { len = 5; // "false"的长度 } }, row[i]); widths[i] = std::max(widths[i], len); } } // 打印表头 for (size_t i = 0; i < headers.size(); i++) { std::cout << std::left << std::setw(widths[i] + 2) << headers[i]; } std::cout << "\n"; for (size_t i = 0; i < headers.size(); i++) { std::cout << std::string(widths[i] + 2, '-'); } std::cout << "\n"; // 打印数据 for (const auto& row : table) { for (size_t i = 0; i < row.size(); i++) { std::visit([&](const auto& arg) { using T = std::decay_t<decltype(arg)>; if constexpr (std::is_same_v<T, std::string>) { std::cout << std::left << std::setw(widths[i] + 2) << arg; } else if constexpr (std::is_same_v<T, int>) { std::cout << std::right << std::setw(widths[i] + 2) << arg; } else if constexpr (std::is_same_v<T, double>) { std::cout << std::fixed << std::setprecision(2) << std::right << std::setw(widths[i] + 2) << arg; } else if constexpr (std::is_same_v<T, bool>) { std::cout << std::right << std::setw(widths[i] + 2) << (arg ? "true" : "false"); } }, row[i]); } std::cout << "\n"; } } int main() { #ifdef _WIN32 // 设置控制台代码页为UTF-8,支持中文输出 SetConsoleOutputCP(CP_UTF8); SetConsoleCP(CP_UTF8); // 设置本地化以支持宽字符输出 std::setlocale(LC_ALL, "zh_CN.UTF-8"); #endif // 读取DBF文件 DBFReader reader("d:\\employees.dbf"); if (!reader.read()) { std::cerr << "Failed to read DBF file. Please make sure 'employees.dbf' exists in the current directory." << std::endl; // 列出当前目录下的文件以帮助调试 std::cout << "Files in current directory:" << std::endl; system("dir *.dbf"); return 1; } std::cout << "DBF file read successfully." << std::endl; // 创建SQL执行器 SQLExecutor executor(reader); // 显示字段信息 std::cout << "Fields in DBF file:" << std::endl; const auto& fields = reader.getFields(); for (const auto& field : fields) { std::string fieldName = processDBFFieldName(field.name, sizeof(field.name)); std::cout << " " << fieldName << " (type: " << field.type << ", length: " << (int)field.length << ")" << std::endl; } // 显示记录数量 std::cout << "Total records: " << reader.getData().size() << std::endl; // 执行SQL查询 - 显示所有记录 std::cout << "\nSQL: SELECT * FROM employees\n"; Table result = executor.execute("SELECT * FROM employees"); // 准备表头 std::vector<std::string> headers; for (const auto& field : reader.getFields()) { std::string fieldName = processDBFFieldName(field.name, sizeof(field.name)); headers.push_back(fieldName); } // 打印结果 printTable(result, headers); // 执行另一个查询 - 查询成绩大于80的学生 std::cout << "\nSQL: SELECT 姓名, 成绩 FROM employees WHERE 成绩 > 80\n"; result = executor.execute("SELECT 姓名, 成绩 FROM employees WHERE 成绩 > 80"); printTable(result, {"姓名", "成绩"}); // 查询特定班级的学生 std::cout << "\nSQL: SELECT 学号, 姓名, 班组 FROM employees WHERE 班组 = '一年一班 '\n"; result = executor.execute("SELECT 学号, 姓名, 班组 FROM employees WHERE 班组 = '一年一班'"); printTable(result, {"学号", "姓名", "班组"}); return 0; }以上代码,数据显示输出有中文乱码,请修复代码
08-16
int main(int argc, char** argv) { cudaSetDevice(DEVICE); std::string wts_name = ""; std::string engine_name = ""; bool is_p6 = false; float gd = 0.0f, gw = 0.0f; //std::string img_dir; if (!parse_args(argc, argv, wts_name, engine_name, is_p6, gd, gw)) { std::cerr << "arguments not right!" << std::endl; std::cerr << "./yolov5_det -s [.wts] [.engine] [n/s/m/l/x/n6/s6/m6/l6/x6 or c/c6 gd gw] // serialize model to plan file" << std::endl; std::cerr << "./yolov5_det -d [.engine] ../samples // deserialize plan file and run inference" << std::endl; return -1; } // create a model using the API directly and serialize it to a stream if (!wts_name.empty()) { IHostMemory* modelStream{ nullptr }; APIToModel(BATCH_SIZE, &modelStream, is_p6, gd, gw, wts_name); assert(modelStream != nullptr); std::ofstream p(engine_name, std::ios::binary); if (!p) { std::cerr << "could not open plan output file" << std::endl; return -1; } p.write(reinterpret_cast<const char*>(modelStream->data()), modelStream->size()); modelStream->destroy(); return 0; } // deserialize the .engine and run inference std::ifstream file(engine_name, std::ios::binary); if (!file.good()) { std::cerr << "read " << engine_name << " error!" << std::endl; return -1; } char *trtModelStream = nullptr; size_t size = 0; file.seekg(0, file.end); size = file.tellg(); file.seekg(0, file.beg); trtModelStream = new char[size]; assert(trtModelStream); file.read(trtModelStream, size); file.close(); // std::vector<std::string> file_names; // if (read_files_in_dir(img_dir.c_str(), file_names) < 0) { // std::cerr << "read_files_in_dir failed." << std::endl; // return -1; // } static float prob[BATCH_SIZE * OUTPUT_SIZE]; IRuntime* runtime = createInferRuntime(gLogger); assert(runtime != nullptr); ICudaEngine* engine = runtime->deserializeCudaEngine(trtModelStream, size); assert(engine != nullptr); IExecutionContext* context = engine->createExecutionContext(); assert(context != nullptr); delete[] trtModelStream; assert(engine->getNbBindings() == 2); float* buffers[2]; // In order to bind the buffers, we need to know the names of the input and output tensors. // Note that indices are guaranteed to be less than IEngine::getNbBindings() const int inputIndex = engine->getBindingIndex(INPUT_BLOB_NAME); const int outputIndex = engine->getBindingIndex(OUTPUT_BLOB_NAME); assert(inputIndex == 0); assert(outputIndex == 1); // Create GPU buffers on device CUDA_CHECK(cudaMalloc((void**)&buffers[inputIndex], BATCH_SIZE * 3 * INPUT_H * INPUT_W * sizeof(float))); CUDA_CHECK(cudaMalloc((void**)&buffers[outputIndex], BATCH_SIZE * OUTPUT_SIZE * sizeof(float))); // Create stream cudaStream_t stream; CUDA_CHECK(cudaStreamCreate(&stream)); uint8_t* img_host = nullptr; uint8_t* img_device = nullptr; // prepare input data cache in pinned memory CUDA_CHECK(cudaMallocHost((void**)&img_host, MAX_IMAGE_INPUT_SIZE_THRESH * 3)); // prepare input data cache in device memory CUDA_CHECK(cudaMalloc((void**)&img_device, MAX_IMAGE_INPUT_SIZE_THRESH * 3)); cv::VideoCapture capture("/media/builderx/UUI/tsy_work/rb002/REC/2024_01_17T14_46_37__stream0.mp4"); //cv::VideoCapture capture(0); cv::Mat frame; int fcount = 0;帮我分析一下每行代码都是什么意思
03-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值