2014-11-20 3 views
0

Я пытаюсь проверить тип моей переменной с помощью функции scanf. Он отлично работает для Dev C++ (мой ввод is int), но он не использует Borland. Вот что я пробовал:scanf в Borland C++ Builder

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

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

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

Любые идеи?

[edit1] переместили от комментариев по Spektre

У меня есть еще одна проблема. Мое значение ввода должно выглядеть как xx-xx-xxxx, так что это дата.
Я должен проверить, являются ли день, месяц и год целыми.
Я пытался так:

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 
} 
  • но проверить только один день. Кто-нибудь знает, почему? - JB 20 часов назад
+0

Когда вы говорите, что это не работает, что вы подразумеваете под этим? Что происходит, когда вы запускаете код, который вы показываете? Пробовали ли вы работать в отладчике и прокладывать линию за строкой, чтобы узнать, что происходит? И почему вы назначаете 'testb', а затем напрямую перезаписываете значение с вызовом' scanf'? –

+0

Можете ли вы объяснить, как здесь можно проверить тип? Вы вычисляете 'testb', а затем выбрасываете его значение в scanf. –

+0

Мне нужно проверить, является ли входное значение числом или символом, потому что мне нужно целое число как тип ввода. –

ответ

0

Я делаю это таким образом

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; 
  • не уверен, если s.ToInt() также так глючит, но, по крайней мере до тех пор, BDS2006
  • , если вы звоните s.ToDouble() за неправильный номер, то исключение unmaskable выбрано
  • так, например, если вы попытаетесь преобразовать 0.98, а десятичная точка не установлена ​​в ., то ваша ошибка программы (atoi и atof безопасны)

вы также можете использовать Sprintf:

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

Спасибо за ваши решения. Это отчасти работает. У меня другая проблема. Мое значение ввода должно выглядеть как xx-xx-xxxx, поэтому это дата. Я должен проверить, являются ли день, месяц и год целыми. Я пробовал вот так: 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} , но он проверяет только один день. Кто-нибудь знает, почему? –

+0

@ J.B. по двум причинам. 1. вы должны добавить скобки для внутренних условий для разделения && операндов (иногда компилятор делает смешные вещи с условием мультипликации, если они не заключены в скобки) 2. AnsiString имеет небольшую ошибку при старшем VCL (включая bds2006), если вы вызываете '... = a.sprintf (...) 'или' ... = a.SubString (...) 'он также изменяет переменную (например, в BCB5 это было нормально, но в BCB6 и BDS2006 ... ее прослушивание) либо хранить подстроки для разделения переменных и вырезать их там после или использовать первый вариант в моем ответе (там, где вы можете жестко скопировать код с пропуском '-' ... он также будет выглядеть намного лучше – Spektre

+0

@JB также проверить в точке останова значение' a.SubString (6,4) ', потому что индексирование AnsiString происходит от 1 не от 0 ... не должно быть' a.SubString (7,4) '(не уверен сейчас и слишком ленив, чтобы проверить его)? – Spektre

1

Вы делаете это ужасно более сложным, чем это должно быть.

scanf() читает с сайта STDIN, но процесс графического интерфейса не использует STDIN для ввода, поэтому он не работает для вас. Используйте sscanf() вместо:

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

В качестве альтернативы, используйте RTL-х TryStrToInt() вместо:

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

Что касается проверки строки даты, вы можете использовать sscanf() для этого:

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

Или использовать RTL TryStrToDate():

TDateTime testb; 

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

if (TryStrToDate(Edit1->Text, testb, fmt)) 
{ 
    // do sth ... 
} 
Смежные вопросы