Your code has several mistakes in it:
you are declaring two Buffer
variables in the same scope. That is not allowed. You need to remove one of them.
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());
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");
}
}