1

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 ファイルです)。getline が生成するため、2 番目の AfxMessageBox には到達しません。

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

誰が何がうまくいかないのか考えていますか?

4

5 に答える 5

1

VS10を使用して問題を解決しました。アルゴリズムは問題なく動作します。しかし、これが解決策になるとは思いません!

同じ PC 上の vs10 で動作することは、PC の問題ではないことも示しています。

于 2012-12-21T18:16:19.047 に答える
0

ファイル オブジェクトを開くときは、使用する前に常に有効であることを確認する必要があります。

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

PSfile同じコードブロックで名前が付けられた2つのオブジェクトがあります。コンパイラがそれをまっすぐに保つことができたとしても、混乱を招く可能性があります。

于 2012-11-26T19:13:58.100 に答える
0

以前にファイルへのパスが含まれていた文字列に行の内容を書き込むのは、おそらく良い考えではありません。次のことを試してください。

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

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

ところで、コードをコピーして貼り付けましたか? あなたが書いたように:

名前空間 std を使用します。

名前空間 stdを使用する代わりに;

于 2012-11-30T13:17:48.470 に答える
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();

結果は?問題が解決しない場合は、2 番目の cout << buf << endl にデバッグ ポイントを設定して、buf に値が割り当てられているかどうかを確認できます。

FileDialog も次のように保護する必要があります。そうしないと、[キャンセル] をクリックすると失敗します。


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

于 2012-11-27T07:28:00.970 に答える