Getline error MFC vs2012 (msvcp110.dll)

2019-02-28 20:23发布

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?

5条回答
唯我独甜
2楼-- · 2019-02-28 21:04

first Let us simplify the issue:

just hard code the path and running it in a new console project:(I added more protection code)


    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();

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.


(dlg.DoModal()==IDOK)
  FilePathName=dlg.GetPathName();
  //....other opertiaon
} 

查看更多
做自己的国王
3楼-- · 2019-02-28 21:07

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.

查看更多
Deceive 欺骗
4楼-- · 2019-02-28 21:07

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.

查看更多
萌系小妹纸
5楼-- · 2019-02-28 21:15

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:

CString csFilePath("C:\\example.txt");
ifstream infile;
infile.open(csFilePath);

std::string strLine;
std::getline(infile, strLine);

By the way, did you copy and paste your code? As you wrote:

usign namespace std;

instead of using namespace std;

查看更多
Melony?
6楼-- · 2019-02-28 21:23

When you open a file object you should always make sure it's valid before trying to use it.

if (file.bad())
    AfxMessageBox("Bad file");
else
{ // existing code follows

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.

查看更多
登录 后发表回答