简体   繁体   English

Borland C ++ Builder中的scanf

[英]scanf in Borland C++ Builder

I'm trying to check type of my variable with function scanf. 我正在尝试使用scanf函数检查变量的类型。 It works fine for Dev C++(my input is int), but it doesn't using Borland. 它对于Dev C ++很好用(我的输入是int),但没有使用Borland。 Here is what I've tried: 这是我尝试过的:

AnsiString as = Edit1->Text;
string b = as.c_str();

int testb = atoi(b.c_str());

if(scanf("%i", &testb)==1){
do sth;
}

Any ideas? 有任何想法吗?

[edit1] moved from comment by Spektre [edit1]从Spektre的评论中移出

I have another problem. 我还有另一个问题。 My input value should look like xx-xx-xxxx so it's a date. 我的输入值应类似于xx-xx-xxxx所以它是一个日期。
I have to check if day, month and year are integer. 我必须检查天,月和年是否为整数。
I tried like this: 我这样尝试过:

AnsiString a = Edit1->Text;
date = a.c_str();
 if (a==AnsiString().sprintf("%i",atoi(a.SubString(0,2).c_str()))
  && a==AnsiString().sprintf("%i",atoi(a.SubString(3,2).c_str()))
  && a==AnsiString().sprintf("%i",atoi(a.SubString(6,4).c_str())) )
 { 
 //do sth
 }
  • but it check only a day. 但它只检查一天。 Does anyone know why? 有人知道为什么吗? – JB 20 hours ago – JB 20小时前

You are making this horribly more complicated than it should be. 您正在使这一过程变得比原本应有的复杂得多。

scanf() reads from STDIN, but a GUI proces does not use STDIN for input, which is why it is not working for you. scanf()从STDIN读取,但是GUI进程不使用STDIN进行输入,这就是为什么它对您不起作用的原因。 Use sscanf() instead: 使用sscanf()代替:

int testb;
if (sscanf(AnsiString(Edit1->Text).c_str(), "%d", &testb) == 1)
{
    // do sth ...
}

Alternatively, use the RTL's TryStrToInt() instead: 或者,可以使用RTL的TryStrToInt()代替:

int testb;
if (TryStrToInt(Edit1->Text, testb))
{
    // do sth ...
}

As for checking a date string, you can use sscanf() for that: 至于检查日期字符串,可以为此使用sscanf()

int day, month, year;
if (sscanf(AnsiString(Edit1->Text).c_str(), "%2d-%2d-%4d", &day, &month, &year) == 3)
{
    // do sth ...
}

Or use the RTL's TryStrToDate() : 或使用RTL的TryStrToDate()

TDateTime testb;

TFormatSettings fmt = TFormatSettings::Create();
fmt.DateSeparator = '-';
fmt.ShortDateFormat = "d-m-y";

if (TryStrToDate(Edit1->Text, testb, fmt))
{
    // do sth ...
}

I do it in this way 我是这样做的

AnsiString s=Edit1->Text; // copy to real AnsiString ... the AnsiStrings inside visual components are not the same ... some functions/operations does not work properly for them
int e,i,l=s.Length();

for(e=0,i=1;i<=l;) 
 {
 e=1; // assume it is integer
 if (s[i]=='-') i++; // skip first minus sign
  for (;i<=l;i++) // scan all the rest 
   if ((s[i]<'0')||(s[i]>'9')) // if not a digit
    { 
    e=0; // then not an integer
    break; // stop
    }
 break;
 }
// here e holds true/false if s is valid integer

now you can use safely
if (e) i=s.ToInt(); else i=0;
  • not sure If s.ToInt() is also so buggy but at least until BDS2006 不确定s.ToInt()是否也是如此,但至少直到BDS2006
  • if you call s.ToDouble() for invalid number then an unmaskable exception is thrown 如果调用s.ToDouble()以获取无效数字,则将引发不可屏蔽的异常
  • so for example if you try to convert 0.98 and the decimal point is not set to . 因此,例如,如果您尝试转换0.98且小数点未设置为. your program crashes (atoi and atof are safe) 您的程序崩溃(atoi和atof是安全的)

you can also use sprintf: 您还可以使用sprintf:

AnsiString s=Edit1->Text;
if (s==AnsiString().sprintf("%i",atoi(s.c_str()))) /* valid integer */;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM