I have a problem to use the std::getline function in vs2012 with an MFC application. The same code was running in vs2010 that's why I am sure that it is not a problem with the code itself.
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();
}
}
The first AfxMessageBox returns the filepath (which is correct and a valid ASCII-file). The Second AfxMessageBox do i never reach because getline produces:
Unhandled exception at 0x000007FEF7B4AAEE (msvcp110.dll) in program.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
and vs11 redirect me to the xiosbase line 443
locale __CLR_OR_THIS_CALL getloc() const
{ // get locale
return (*_Ploc);/*THIS IS LINE 443*/
}
For the project property i am using "Use MFC in a shared dll" and "Multi-threaded DLL" and Sub-System "Windows"
Additional program code and includes:
#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);
}
}
}
Anyone an idea what is going wrong?
first Let us simplify the issue:
just hard code the path and running it in a new console project:(I added more protection code)
what is the result? if issue is still, your can set a debug point at the second cout << buf << endl to check if buf is assigned with a value.
You should also protect the FileDialog as following: or once click 'cancel', it will fail.
I have solved the problem now by using VS10. There the algorithm works without any issues. But I do not think that this can be the solution!
That it works with vs10 on the same PC tells me also that it is not a problem with the PC.
It was working and is not anymore.
Change the compilation flag (in the project Properties > Configuration Properties > C++ > Code Generation > Runtime Library) from
/MD
(multi-threaded DLL) to/MDd
(multi-threaded debug DLL), for both Debug & Release configurations.This should work in VisualStudio 2012 at least.
Maybe it is not a good idea to write the line content in the string which contained the path to the file before. Try the following:
By the way, did you copy and paste your code? As you wrote:
instead of using namespace std;
When you open a file object you should always make sure it's valid before trying to use it.
P.S. You have two objects named
file
in the same block of code. Please don't do that, it's potentially confusing even if the compiler is able to keep it straight.