1

我是编程新手。实际上我在大学二年级并开始实习。他们想让我在 C++ builder 中做一个程序,但我只知道 C。我学了什么。而且我对OOP一无所知。

所以我的问题是。

我有 TEdit1,我想验证该文本框中引入的数据是否是数字。我知道要验证它是否是一个数字,但我不知道如何将 TEdit 中的数据放入字符串中。

我写了一些代码,但它不起作用。

void __fastcall TForm1::Button1Click(TObject *Sender) 
{
    int Size = Edit1->GetTextLen(); //Get length of string in Edit1
    Size++;                         //Add room for null character
    Char *Buffer = new Char[Size];  //Creates Buffer dynamic variable

    std::auto_ptr<Char> Buffer(new Char[Size]);

    Edit1->GetTextBuf(Buffer.get(),Size); //Puts Edit1->Text into Buffer

    ShowMessage(Buffer);
}

我得到这些错误:

 E2034 Cannot convert 'std::auto_ptr<wchar_t>' to 'UnicodeString'
 E2342 Type mismatch in parameter 'Msg' (wanted 'const UnicodeString', got              std::auto_ptr<wchar_t>')

你能解释一下我做错了什么,或者我在哪里可以找到 Embarcadero C++ Builder 教程?我搜索了所有谷歌并没有找到可以帮助我的东西。

4

1 回答 1

2

Your code has several mistakes in it:

  1. you are declaring two Buffer variables in the same scope. That is not allowed. You need to remove one of them.

  2. you are passing the std::auto_ptr itself to ShowMessage(), but it expects a System::UnicodeString instead, thus the compiler error message. You can use the std::auto_ptr::get() method to get the wchar_t* pointer and pass it to ShowMessage(), as UnicodeString has a constructor that accepts wchar_t* as input:

    ShowMessage(Buffer.get());
    
  3. despite the above, you actually cannot use a pointer from new[] with std::auto_ptr to begin with. std::auto_ptr uses delete instead of delete[] to free the memory being pointed at. You must always use delete with new, and delete[] with new[]. So, while the code will compile, it will not free the memory correctly at runtime. C++11 introduced a new std::unique_ptr class to replace std::auto_ptr, and std::unique_ptr supports new[] and delete[] (however, C++Builder's 32bit compiler does not support C++11 yet - that is in the works - but its 64bit compiler does):

    #include <memory>
    
    void __fastcall TForm1::Button1Click(TObject *Sender) 
    {
        int Size = Edit1->GetTextLen(); //Get length of string in Edit1
        Size++;                         //Add room for null character
    
        std::unique_ptr<Char[]> Buffer(new Char[Size]); //Creates Buffer dynamic variable
    
        Edit1->GetTextBuf(Buffer.get(), Size); //Puts Edit1->Text into Buffer
    
        ShowMessage(Buffer.get());
    }
    

Now, with that said, if you are going to continue using C++Builder, you should learn how to use its built-in functionalities, like UnicodeString, which the RTL/VCL relies heavily on (use the System::String alias for most code, use UnicodeString directly only when absolutely necessary).

Your example can be vastly simplified using the TEdit::Text property:

void __fastcall TForm1::Button1Click(TObject *Sender) 
{
    String s = Edit1->Text; //Get string in Edit1
    ShowMessage(s);
}

The simplest solution to your problem would be to use the TCSpinEdit component instead of TEdit, as TCSpinEdit only allows numeric input in the first place, and has a Value property that returns an int:

void __fastcall TForm1::Button1Click(TObject *Sender) 
{
    int number = CSpinEdit1->Value;
    ShowMessage("It is a number");
    // use number as needed...
}

But, if you have to stick with TEdit, there are many ways to check a UnicodeString for numeric content.

You can set the TEdit::NumbersOnly property to true so the user cannot enter a non-numeric value (unless they use copy/paste, but let's ignore that for the moment), and then use the RTL's StrToInt() function, or System::UnicodeString::ToInt() method, to convert it as-is:

#include <System.SysUtils.hpp>

void __fastcall TForm1::Button1Click(TObject *Sender) 
{
    int number;

    try
    {
        number = StrToInt(Edit1->Text);
        // or: number = Edit1->Text.ToInt();
    }
    catch (const EConvertError&)
    {
        // not a number, do something else...
        ShowMessage("It is not a number");
        return;
    }

    ShowMessage("It is a number");
    // use number as needed...
}

Or you can use the RTL's System::Sysutils::TryStrToInt() function:

#include <System.SysUtils.hpp>

void __fastcall TForm1::Button1Click(TObject *Sender) 
{
    int number;

    if (TryStrToInt(Edit1->Text, number))
    {
        // use number as needed...
        ShowMessage("It is a number");
    }
    else
    {
        // not a number, do something else...
        ShowMessage("It is not a number");
    }
}

Or you can use the STL's std::wistringstream class:

#include <sstream>

void __fastcall TForm1::Button1Click(TObject *Sender) 
{
    int number;

    std::wistringstream iss(Edit1->Text.c_str());
    if (iss >> number)
    {
        // use number as needed...
        ShowMessage("It is a number");
    }
    else
    {
        // not a number, do something else...
        ShowMessage("It is not a number");
    }
}

Or, since you have a C background, you can use the C _wtoi() function (which doesn't offer much in the way of error checking):

#include <cstdlib>

void __fastcall TForm1::Button1Click(TObject *Sender) 
{
    int number = std::_wtoi(Edit1->Text.c_str());
    if (number != 0)
    {
        // use number as needed...
        ShowMessage("It is a valid number");
    }
    else
    {
        // not a number, do something else...
        ShowMessage("It is not a valid number");
    }
}

Or you can use the C wcstol() function:

#include <cstdlib>

void __fastcall TForm1::Button1Click(TObject *Sender) 
{
    String s = Edit1->Text;
    Char *p = s.c_str(), *end;
    int number = std::wcstol(p, &end, 10);
    if (end != p)
    {
        // use number as needed...
        ShowMessage("It is a number");
    }
    else
    {
        // not a number, do something else...
        ShowMessage("It is not a number");
    }
}

Or you can use the C swscanf() function:

#include <cstdio>

void __fastcall TForm1::Button1Click(TObject *Sender) 
{
    int number;

    if (std::swscanf(Edit1->Text.c_str(), L"%d", &number) == 1)
    {
        // use number as needed...
        ShowMessage("It is a number");
    }
    else
    {
        // not a number, do something else...
        ShowMessage("It is not a number");
    }
}
于 2015-07-18T01:43:58.660 回答