C++初学者读取文件夹图片遇std::vector push_back类型匹配错误求助
问题解决:std::vector push_back 类型不匹配错误
错误信息
Severity Code Description Project File Line Suppression State Detail Description Error (active) E0304 no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back [with _Ty=cv::String, _Alloc=std::allocator<cv::String>]" matches the argument list HelloWorld D:\VS Projects\HelloWorld\HelloWorld\HelloWorld.cpp 103 argument types are: (WCHAR [260]) object type is: std::vector<cv::String, std::allocator<cv::String>>
问题根源
错误出在names_ofFiles.push_back(Info.cFileName);这一行:
Info是WIN32_FIND_DATAW类型,其cFileName成员是宽字符数组(WCHAR[260])- 而
names_ofFiles是std::vector<std::string>,存储的是窄字符字符串 - 两种字符类型不兼容,导致
push_back找不到匹配的重载函数
另外代码中还有一处错误:用wprintf处理窄字符路径folderPath,会导致路径转换失败,应该使用宽字符安全格式化函数。
解决方案
方案1:将宽字符转换为窄字符串(推荐)
添加一个宽字符转std::string的工具函数,同时修复路径格式化的问题:
- 新增转换函数:
// 宽字符转UTF-8窄字符串 std::string wcharToString(const wchar_t* wstr) { int bufferSize = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr); std::string str(bufferSize, 0); WideCharToMultiByte(CP_UTF8, 0, wstr, -1, &str[0], bufferSize, nullptr, nullptr); return str; }
- 修改路径格式化代码:
wchar_t search[200]; // 先将窄字符路径转宽字符 wchar_t folderPathWide[200]; MultiByteToWideChar(CP_UTF8, 0, folderPath.c_str(), -1, folderPathWide, 200); // 用安全宽字符格式化函数,添加路径分隔符避免路径错误 swprintf_s(search, L"%s\\*.*", folderPathWide);
- 修改
push_back的调用:
names_ofFiles.push_back(wcharToString(Info.cFileName));
方案2:全程使用宽字符(需适配OpenCV)
如果想全程用宽字符,需要把vector<string>改成vector<wstring>,但OpenCV的imread不直接支持宽字符路径,读取图片时仍需转成窄字符:
// 宽字符转窄字符后调用imread string cesta = wcharToString((Path2Wide + vectorOfFileNameWithinPath[i]).c_str()); Mat img = imread(cesta, IMREAD_COLOR);
额外修复建议
- 循环条件错误:原代码
for (int i = 0; i < vectorOfFileNameWithinPath.size() - 1; ++i)会漏掉最后一个文件,改成i < vectorOfFileNameWithinPath.size() - 路径拼接错误:原代码
string cesta = Path2 + vectorOfFileNameWithinPath[i]缺少路径分隔符,应该改成string cesta = Path2 + "\\" + vectorOfFileNameWithinPath[i],否则路径会变成C:\...\Imagesfilename.jpg,导致imread失败 - 添加图片读取检查:如果图片路径错误,
imread会返回空Mat,添加判断可以避免后续操作出错
修复后的完整代码示例
#include <opencv2/opencv.hpp> #include "opencv2\highgui.hpp" #include "opencv2\imgproc.hpp" #include <vector> #include <fstream> #include <stdio.h> #include <iostream> #include <Windows.h> #include <iomanip> #include<string.h> using namespace cv; using std::vector; using std::string; using namespace std; // 宽字符转UTF-8窄字符串 std::string wcharToString(const wchar_t* wstr) { int bufferSize = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr); std::string str(bufferSize, 0); WideCharToMultiByte(CP_UTF8, 0, wstr, -1, &str[0], bufferSize, nullptr, nullptr); return str; } vector<string> getNamesOfFile(string folderPath) { std::vector<string> names_ofFiles; wchar_t search[200]; // 将窄字符路径转换为宽字符 wchar_t folderPathWide[200]; MultiByteToWideChar(CP_UTF8, 0, folderPath.c_str(), -1, folderPathWide, 200); // 格式化搜索路径,添加路径分隔符和通配符 swprintf_s(search, L"%s\\*.*", folderPathWide); WIN32_FIND_DATAW Info; HANDLE Find = ::FindFirstFileW(search, &Info); if (Find != INVALID_HANDLE_VALUE) { do { if (!(Info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { // 转换宽字符文件名后加入vector names_ofFiles.push_back(wcharToString(Info.cFileName)); } } while (::FindNextFile(Find, &Info)); ::FindClose(Find); } return names_ofFiles; } int main(int argc, const char** argv) { string Path2 = "C:\\Users\\Ksheeraja K S\\OneDrive\\Pictures\\Images"; vector<string> vectorOfFileNameWithinPath = getNamesOfFile(Path2); int pos_count = 0; std::vector<Mat> StoredImages; // 修复循环条件,不要漏掉最后一个文件 for (int i = 0; i < vectorOfFileNameWithinPath.size(); ++i) { // 拼接路径时添加分隔符 string cesta = Path2 + "\\" + vectorOfFileNameWithinPath[i]; Mat img = imread(cesta, IMREAD_COLOR); // 检查图片是否成功读取 if (img.empty()) { cout << "无法读取图片: " << cesta << endl; continue; } StoredImages.push_back(img); namedWindow("Display", WINDOW_AUTOSIZE); imshow("Display", img); int key1 = waitKey(10); pos_count++; } destroyAllWindows(); return 0; }
内容的提问来源于stack exchange,提问作者Ksheeraja Shrinivas
相关产品推荐
相关产品推荐

