Перейти к содержанию
    

Как правильно делается sscanf для TEdit->Text

Изучаю работу в окнах под C++Builder 6, до этого писаль только консольные приложеня.

 

Вопрос следующий, есть масив

unsigned char IP[4];

потом на форме есть VCL компонент типа TEdit * EditIP, в поле которого пишется ИП адрес

в таком виде - 192.168.0.1

 

собственно в консольном приложении я делал так

scanf("%d.%d.%d.%d", &IP_server[0], &IP_server[1], &IP_server[2], &IP_server[3]);

 

А как такое делается в Builder ? подскажите

 

 

так не работает

sscanf(&IP[0],"%d.%d.%d.%d", Edit_IP->Text);

тоесть когда вывожу отладочную информацию то масив IP[] содержит одни нули

 Memo1->Lines->Add(d_str.sprintf("IP %d.%d.%d.%d", IP[0],IP[1],IP[2],IP[3]) );

 

для проверки

Memo1->Lines->Add(Edit_Login->Text);

то ип переносится нормально

 

подскажите что неправильно ?

Изменено пользователем west329_

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

так не работает

sscanf(&IP[0],"%d.%d.%d.%d", Edit_IP->Text);

тоесть когда вывожу отладочную информацию то масив IP[] содержит одни нули

Естественно, потому что Edit_IP->Text не типа char *. Как превратить String (или что там) в char *, изучайте доку на VCL.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос следующий, есть масив
unsigned char IP[4];

потом на форме есть VCL компонент типа TEdit * EditIP, в поле которого пишется ИП адрес

в таком виде - 192.168.0.1

 

подскажите что неправильно ?

 

Сначала пользователь заводит в Edit текстовую строку "в таком виде - 192.168.0.1". И здесь ничего руками писать не надо...

Далее - текстовая строка представляет уже собой массив. Поэтому делаете строковую переменную String IP и ей присваиваете Edit->Text...

Далее смотрите по хелпу, как получить доступ к символам строки.

Смотрите функцию поиска символа в строке. Либо вручную перебираете символы и находите первую точку, либо пользуетесь функцией Билдера...

У меня на сайте выложен пример софта для работы с JTAG. Там есть файл работы со строками. Все откоментировано достаточно подробно...

Удачи!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне другое интересно - как это по формату %d вводится не в int, а в unsigned char?

Я понимаю, что везёт - и LOW ENDIAN (ну об этом действительно практически всегда можно забыть), и после массива unsigned char IP[4] просто случайно оказалось ненужное в данный момент место (а вот это уже "чревато боком" для любого процессора) и его не страшно протереть нулями при работе (s)scanf, но... Непривычно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне другое интересно - как это по формату %d вводится не в int, а в unsigned char?

 

Верное замечание! Формат %d для вывода в char-переменные не годится. А формат %hd далеко не все компиляторы поддерживают. Надежнее, да и ближе к стандарту, завести переменные типа int (хотя бы временные), а том из них скопировать в char.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нельзя недооценивать пользователя. Он запросто может ввести в это поле что угодно, вплоть до собственного имени, даты рождения или номера паспорта. Для разбора таких данных sscanf() уже мало пригодна, она больше для неинтерактивных данных, где есть уверенность что нужный формат соблюдается.

Нужно проконтролировать что числа находятся в диапазоне 0-255, что между ними действительно только одна точка, что чисел всего четыре, не больше и не меньше, и по любой ошибке выдать осмысленное сообщение.

Лучше разбирать строку по частям. Можно просто вручную считывать цифры и превращать их в число или применить функции типа atoi() или strtol(), потом проверить на '.', потом следующее число...

 

Ещё лучше сделать четыре отдельных поля ввода, по одному для каждого числа, проще будет и точек юзеру набирать не надо, они уже будут нарисованы на форме для ввода.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ещё лучше сделать четыре отдельных поля ввода, по одному для каждого числа, проще будет и точек юзеру набирать не надо, они уже будут нарисованы на форме для ввода.

И при вводе контролировать правильность ввода по диапазону чисел при уходе фокуса ввода на другой элемент. Нечто аналогичное есть в MFC (Edit).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для разбора таких данных sscanf() уже мало пригодна, она больше для неинтерактивных данных, где есть уверенность что нужный формат соблюдается.
Если это разбор конфига - то ничем не отличается от ввода с экрана, может оказаться всё, что угодно.

 

Нужно проконтролировать что числа находятся в диапазоне 0-255, что между ними действительно только одна точка, что чисел всего четыре, не больше и не меньше, и по любой ошибке выдать осмысленное сообщение.

Лучше разбирать строку по частям. Можно просто вручную считывать цифры и превращать их в число или применить функции типа atoi() или strtol(), потом проверить на '.', потом следующее число...

Ну если опускаться до "а вот восьмым символом строки после второго числа у Вас запятая, а там надо бы точку", то, конечно, со scanf-ом туго. А так - scanf вполне нормальная штука:

#include <stdio.h>

void scan_ip(const char *str)
{
    unsigned IP[4];
    char ch;
    
    printf( "`%s' : ", str);

    int result = sscanf( str, "%u.%u.%u.%u%c", IP, IP+1, IP+2, IP+3, &ch);

    if(  result == 5 ) {
        printf( "extra character in string\n");
    } else if( result < 4) {
        printf( "not all numbers entered, may be numbers delimited with invalid character\n");
    } else if( IP[0] > 255 || IP[1] > 255 || IP[2] > 255 || IP[3] > 255) {
        printf( "numbers must be in range 0..255\n");
    } else {
        printf( "valid IP = %u.%u.%u.%u\n", IP[0], IP[1], IP[2], IP[3] );
    }
}


int main()
{
    scan_ip( "192.168.0.1" );
    scan_ip( "192.168.0" );
    scan_ip( "192168.0.1.2" );
    scan_ip( "192.168.0.1*" );
    scan_ip( "192.168,0.1" );
    scan_ip( "-192.168.0.1" );

    return 0;
}

`192.168.0.1' : valid IP = 192.168.0.1
`192.168.0' : not all numbers entered, may be numbers delimited with invalid character
`192168.0.1.2' : numbers must be in range 0..255
`192.168.0.1*' : extra character in string
`192.168,0.1' : not all numbers entered, may be numbers delimited with invalid character
`-192.168.0.1' : numbers must be in range 0..255

Думаю, такой диагностики достаточно и нет смысла врукопашную atoi-чить.

 

Ещё лучше сделать четыре отдельных поля ввода, по одному для каждого числа, проще будет и точек юзеру набирать не надо, они уже будут нарисованы на форме для ввода.
Это другое дело.

Заодно можно, как это уже реализовано то там, то сям - при выходе из поля если оно оставлено пустым - занулять.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С пробелами хуже... "192. 168. 0.1" указанным фрагментом кода воспринимается нормально.

Можно попробовать сначала втащить в промежуточную строку, заодно ограничив длину 15 символов и сделав допустимыми только символы цифр и точку

 char tmpstr[16];
sscanf( str, "%15[0-9.]s", tmpstr);

и дальше разбирать уже tmpstr

Но по мере наворачивания изобретательности пользователя и необходимости объяснять ему, где он неправ, разжёвывая до выделения красным мест во введённой строке, может оказаться проще действительно вручную разбирать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

счас уже самолет получится...

вопрос был про C++Builder - так почему не воспользоваться его средствами?

есть-же не только Edit, но и "MaskEdit" - не помню точно как называется - можно сразу задать допустимый для ввода шаблон.

Или что-то типа такого (давно с C++Builder слез):

     TStringList* Strings = new TStringList();
     Strings->CommaText = Edit->Text; /*->CommaText ждет ',' - т.е. нужно задать разделителем точку*/
     if(Strings->Count==4) {
         /*разбор Strings, возможно, через StrToInt() или ->AsInteger*/

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Или что-то типа такого (давно с C++Builder слез):

 

А чем сейчас пользуетесь если не секрет.

Я взял старенький С потомучто ему не нужна NET платформа, Builder потому что экономит львиную часть времени если работать с окнами мелкософта.

 

есть хорошая альтернатива ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

есть-же не только Edit, но и "MaskEdit" - не помню точно как называется - можно сразу задать допустимый для ввода шаблон.

Защита от дурака это хорошо, но пользователь - всегда прав. Поэтому защиту от дурака надо делать после того как пользователь ввел все что хотел и нажал "ОК", а не до. В MaskEdit же эта защита сделана "до". В результате чего, MaskEdit - это неюзабельная вещь. Поди разбери что он (этот MaskEdit) от тебя хочет, и почему проглатывает символы. Кнопки давишь, а ничего не вводится. Фтопку.

 

Если программа не дает пользователю ввести символы которые он хочет ввести, то место такой программе - в корзине.

 

 

PS: Мелкософт тоже маладцы блин, при конфигурировании TCP/IP если ошибочно задатать octet IP адреса скажем не 30, а 300 - автоматически получим в поле ввода 255.

И вместо того чтобы раз нажать del - придется перевводить все число наново. Спрашивается а нафига такой ителлект вводилки нужен?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В MaskEdit же эта защита сделана "до". В результате чего, MaskEdit - это неюзабельная вещь.

Если мне память не изменяет, то у MaskEdit можно задать обработчик события неправильного ввода - т.е. можно выводить подсказки, поправлять ввод, ...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...