我在使用带有MFC应用程序的vs2012中的std :: getline函数时遇到问题。在vs2010中运行相同的代码,这就是为什么我确信这不是代码本身的问题。
void AddImage::OnClickedIdbAiRegistration(){
CFileDialog file(TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, "(*.dat)|*.dat||");
file.DoModal();
UpdateData();
m_ai_file=file.GetPathName();
UpdateData(FALSE);
std::string buf=m_ai_file;
if(filecnt(buf, "Dat")){
std::ifstream file(buf);
AfxMessageBox(buf.c_str());
std::getline(file, buf);//Here is my problem
AfxMessageBox(buf.c_str());
file.close();
}
}
第一个AfxMessageBox返回文件路径(正确且有效的ASCII文件)。我从未到达第二个AfxMessageBox因为getline产生:
program.exe中0x000007FEF7B4AAEE(msvcp110.dll)的未处理异常:0xC0000005:访问冲突读取位置0xFFFFFFFFFFFFFFFF。
和vs11将我重定向到xiosbase行443
locale __CLR_OR_THIS_CALL getloc() const
{ // get locale
return (*_Ploc);/*THIS IS LINE 443*/
}
对于项目属性,我使用“在共享dll中使用MFC”和“多线程DLL”和子系统“Windows”
其他程序代码,包括:
#include <afxwin.h>
#include <afxframewndex.h>
#include <afxcmn.h>
#include <afxdialogex.h>
#include <iostream>
#include <string>
#include <sstream>
#include <regex>
#include <fstream>
#include <time.h>
#include <Windows.h>
usign namespace std;
class AddImage:public CDialog{
DECLARE_DYNAMIC(AddImage)
public:
AddImage(CWnd* pParent = NULL);
virtual ~AddImage();
enum {IDD=IDD_ADD_IMAGE};
protected:
virtual void DoDataExchange(CDataExchange* pDX);
DECLARE_MESSAGE_MAP()
public:
CString m_ai_file;
};
AddImage::AddImage(CWnd* pParent):CDialog(AddImage::IDD, pParent){
m_ai_file=_T("");
}
AddImage::~AddImage(){
}
bool filecnt(string path, string type){
if(filepathcnt(path, type)){
if(GetFileAttributes(path.c_str())==-1){
return(FALSE);
}
else{
return(TRUE);
}
}
else{
return(FALSE);
}
}
bool filepathcnt(string path, string type){
if(type==""){
tr1::regex regex("[[:print:]]+\\.[[:alnum:]]+");
if(regex_match(path.begin(), path.end(), regex)){
return(TRUE);
}
else{
return(FALSE);
}
}
else if(type=="-"){
tr1::regex regex("[[:print:]]+");
if(regex_match(path.begin(), path.end(), regex)){
return(TRUE);
}
else{
return(FALSE);
}
}
else{
string upper=type;
string lower=type;
transform(upper.begin(), upper.end(), upper.begin(), toupper);
transform(lower.begin(), lower.end(), lower.begin(), tolower);
tr1::regex norm_regex("[[:print:]]+\\."+type);
tr1::regex upper_regex("[[:print:]]+\\."+upper);
tr1::regex lower_regex("[[:print:]]+\\."+lower);
if(regex_match(path.begin(), path.end(), upper_regex) || regex_match(path.begin(), path.end(), lower_regex) || regex_match(path.begin(), path.end(), norm_regex)){
return(TRUE);
}
else{
return(FALSE);
}
}
}
任何人都知道出了什么问题?
答案 0 :(得分:1)
我现在使用VS10解决了这个问题。那里的算法没有任何问题。但我认为这不是解决方案!
它在同一台PC上与vs10配合使用也告诉我它不是PC的问题。
答案 1 :(得分:0)
当您打开文件对象时,应始终确保它在尝试使用之前有效。
if (file.bad())
AfxMessageBox("Bad file");
else
{ // existing code follows
P.S。在同一代码块中有两个名为file
的对象。请不要这样做,即使编译器能够保持原状,也可能会造成混淆。
答案 2 :(得分:0)
首先让我们简化问题:
只需硬编码路径并在新的控制台项目中运行它:(我添加了更多保护代码)
String buf="the data file path";
std::ifstream file(buf);
if(!file.is_open())
return FALSE;
while(file.good())
{
cout << buf << endl;
std::getline(file, buf);
cout << buf << endl;
}
file.close();
结果如何?如果问题仍然存在,你可以在第二个cout&lt;&lt; buf&lt;&lt; endl检查是否为buf分配了值。
您还应该保护FileDialog,如下所示:或者一旦点击“取消”,它将失败。
(dlg.DoModal()==IDOK)
FilePathName=dlg.GetPathName();
//....other opertiaon
}
答案 3 :(得分:0)
在包含之前文件路径的字符串中写入行内容可能不是一个好主意。请尝试以下方法:
CString csFilePath("C:\\example.txt");
ifstream infile;
infile.open(csFilePath);
std::string strLine;
std::getline(infile, strLine);
顺便问一下,你复制并粘贴了你的代码吗?正如你写的那样:
usign namespace std;
而不是使用命名空间std;
答案 4 :(得分:0)
它正在运作,现在已经不存在了。
将编译标志(在项目属性&gt;配置属性&gt; C ++&gt;代码生成&gt;运行时库)中从/MD
(多线程DLL)更改为/MDd
(多线程)调试DLL),用于Debug&amp;发布配置。
这应该至少在VisualStudio 2012中有效。