C++/Win32 构造函数未使用从对话框获得的字符串初始化变量

Posted

技术标签:

【中文标题】C++/Win32 构造函数未使用从对话框获得的字符串初始化变量【英文标题】:C++/Win32 constructor not initializing variable with string obtained from dialog 【发布时间】:2019-11-28 15:01:33 【问题描述】:

我正在尝试使用从对话框获取的 std::string 创建一个对象,调试时我看到它已成功获取并传递给构造函数,但是本地参数保持为“”。

这是我的班级标题:

#pragma once
#include <iostream>
#include <istream>
#include <fstream>
#include <string>

class Motorcycle

public:
    Motorcycle();
    Motorcycle(const std::string& nameP, int mileage) : name(nameP), mileage(mileage) ;

    friend std::ostream & operator << (std::ostream & out, const Motorcycle & obj)
    
        out << obj.name << "\n" << obj.mileage << std::endl;
        return out;
    ;

    //friend std::istream & operator >> (std::istream & in, const Motorcycle & obj)
    //
    //  in >> &obj.name[0] >> obj.mileage;
    //  return in;
    //;

private:
    std::string name;
    int mileage;
;

cpp 还是空的(我想也许我应该把构造函数放在那里,但结果是一样的?):

#include "stdafx.h"
#include "Motorcycle.h"
#include <string>

Motorcycle::Motorcycle()



//Motorcycle::Motorcycle(const std::string &nameP, int mileage) : name(nameP), mileage(mileage) ;

这是对话框加上其他功能的过程:

    BOOL CALLBACK CreateBikeProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

    std::string name = "";
    int mileage;

    switch (message)
    
    case WM_INITDIALOG:

        return TRUE;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        
        case IDOK:
            GetDlgItemTextA(hWnd, IDC_EDIT_NAME, &name[0], 16);
            mileage = GetDlgItemInt(hWnd, IDC_EDIT_MILEAGE, NULL, FALSE);
            if (ValidateBike(name, mileage))
            
                CreateBike(name, mileage);
                EndDialog(hWnd, IDOK);
            
            break;
        case IDCANCEL:
            EndDialog(hWnd, IDCANCEL);
            break;
        
        break;
    default:
        return FALSE;
    
    return TRUE;


BOOL ValidateBike(std::string& name, int mileage)

    if (name[0] == ' ' || name.find_first_not_of(' ') != name.npos
        || mileage < 1)
        return false;
    
    return true; 

BOOL CreateBike(std::string& name, int mileage)


    Motorcycle bike = Motorcycle(name, mileage);
    
    std::ofstream ofs("motorcycles.txt", std::ios::app);
    ofs << bike;
    ofs.close();

    return true;

我可以看到 CreateBikeProc 中的名称已分配并传递给其他函数,但是 bike.name 为空...

此外,friend std::istream &amp; operator &gt;&gt; 被注释掉,因为它会导致另一个错误... Error 1 error C2678: binary '&gt;&gt;' : no operator found which takes a left-hand operand of type 'std::istream' (or there is no acceptable conversion)

提前谢谢...

【问题讨论】:

不应该是Motorcycle bike = new Motorcycle(name, mileage);吗? 不应该,@devb。这是 C++,不是 Java。 @SamVarshavchik 非常真实,很抱歉。虽然在我的情况下它是 C# 我搞混了 :-D。 好吧,作为一个半答案(或者可能是四分之一答案):您的 &gt;&gt; 重载将无法正常工作,因为您已将 Motorcycle 参数声明为 const ...并且您不能将来自流或其他任何地方的数据输入到const。此外,namestd::string 不是 char 数组,因此请使用 in &gt;&gt; obj.name &gt;&gt; obj.mileage;(不是 &amp;obj.name[0])。 我认为问题在于如何访问传递给 GetDlgItemTextA 函数的名称变量的缓冲区。您应该为它分配内存,或者通过适当的成员函数和 std:string 返回它 【参考方案1】:

问题出在这里:

GetDlgItemTextA(hWnd, IDC_EDIT_NAME, &name[0], 16);

您不能像这样将值读入字符串。您需要创建一个缓冲区,然后从缓冲区更新字符串:

char buffer[17]="";
GetDlgItemTextA(hWnd, IDC_EDIT_NAME, &buffer, 16);
name=buffer;

对于operator&gt;&gt;,您有两个问题:第一个是const Motorcycle 参数,第二个是您试图就地覆盖字符串。这是一个固定版本:

    friend std::istream & operator >> (std::istream & in, Motorcycle & obj)
    
      in >> obj.name >> obj.mileage;
      return in;
    ;

【讨论】:

请随时为我在评论中给出的&gt;&gt; 添加“修复”!那么这将是一个好的答案和一个完整的答案。 谢谢你们俩:D

以上是关于C++/Win32 构造函数未使用从对话框获得的字符串初始化变量的主要内容,如果未能解决你的问题,请参考以下文章

win32 C++ 打印 PRINTDLGEX 未声明?

Win10开机出现位置不可用C:Windowssystem32configsystemprofileDesktop不可用点关闭对话框桌面图标文件夹不见

怎么样学习熟练win32 api?需要掌握哪些知识点、要点?

怎样用win32 API函数弹出对话框

GetOpenFileName函数未打开对话框

使用 GDIPlus (WIN32 C++) 显示存储为 alpha 资源的图标