2009-12-30 2 views
1

Я написал функцию для записи данных с помощью считывателя SITE IDENTity MaX AVI и проанализировал код объекта и номер ключа. Как я сейчас это делаю, но есть ли лучший способ? Кажется немного хак ... любитель & ЬиХ являются размером 264Преобразование Hex Char Int Int - Есть ли лучший способ?

buf и buff являются обугливается

Данные, полученным от читателя:

2009/12/30 14:56:18 epc0 LN:001 C80507A0008A19FA 0000232F Xlat'd

char TAccessReader::HexCharToInt(char n) 
{ 
    if (n >= '0' && n <= '9') 
     return (n-'0'); 
    else 

    if (n >= 'A' && n <= 'F') 
     return (n-'A'+10); 
    else 
     return 0; 
} 

bool TAccessReader::CheckSirit(char *buf, long *key_num, unsigned char *fac) { 

    unsigned short i, j, k; 

    *key_num = 0; // Default is zero 
    memset(buff, 0, sizeof(buff)); 

    i = sscanf(buf, "%s %s %s %s %s %s %s", &buff[0], &buff[20], &buff[40], 
       &buff[60], &buff[80], &buff[140], &buff[160]); 
    if (i == 7 && buff[147] && !buff[148]) { 
     // UUGGNNNN UU=spare, GG=Facility Code, NNNN=Keycard Number (all HEX) 

     // get facility code 

     *fac = HexCharToInt(buff[142]) * 16 + HexCharToInt(buff[143]); 
     *key_num = (unsigned short)HexCharToInt(buff[144]) * 4096 + 
        (unsigned short)HexCharToInt(buff[145]) * 256 + 
        (unsigned short)HexCharToInt(buff[146]) * 16 + 
        HexCharToInt(buff[147]); 
    } 
    // do some basic checks.. return true or false 
} 
+0

Каков формат buf? –

+0

Вы можете использовать 'strtoul()' из стандартной библиотеки C. –

+0

'strtol' и' strtoul' re мои любимые функции для этого, потому что они настолько гибкие. Они могут делать шестнадцатеричные, десятичные, восьмеричные и двоичные (любая база от 2 до 36, действительно), и если вы скажете base 0, они будут использовать префиксы C-стиля ('0' для восьмеричного,' 0x' для hex, нет префикса для десятичного), чтобы выяснить базу. Отлично подходит для анализа параметров. Единственное, чего они не делают, это база 64. –

ответ

1

Вот простой способ получить на данные, которые вы хотите , Я действительно работаю в бизнесе контроля доступа, поэтому это было то, что меня заинтересовало ...

template<typename TRet, typename Iterator> 
TRet ConvertHex(Iterator begin) { 
    unsigned long result; 

    Iterator end = begin + (sizeof(TRet) * 2); 
    std::stringstream ss(std::string(begin, end)); 
    ss >> std::hex >> result; 

    return result; 
} 

bool TAccessReader::CheckSirit(char *buf, long *key_num, unsigned char *fac) { 
    *key_num = 0; // Default is zero 

    std::istringstream sbuf(std::string(buf, buf+264)); 

    // Stuff all of the string elements into a vector 
    std::vector<std::string> elements; 
    std::copy (std::istream_iterator<std::string>(sbuf), std::istream_iterator<std::string>(), std::back_inserter (elements)); 

    // We're interested in the 6th element 
    std::string read = elements[5]; 

    if (read.length() == 8) { 
     // UUGGNNNN UU=spare, GG=Facility Code, NNNN=Keycard Number (all HEX) 

     // get facility and card code 
     std::string::const_iterator iter = read.begin(); 
     *fac = ConvertHex<unsigned char>(iter + 2); 
     *key_num = ConvertHex<unsigned short>(iter + 4); 
    } 
    // do some basic checks.. return true or false 
} 
+0

получение этой ошибки: «оператор <<» не реализован в типе «строка» для аргументов типа «istringstream» – 2009-12-30 19:35:10

+0

Да, извините, это должно было быть> > не <<. Я все равно изменил код, поэтому попробуйте новые товары. – joshperry

+0

Я думаю, что его отсутствует что-то, потому что оно не компилируется должным образом. Undefined symbol 'is' и' read' – 2009-12-30 19:51:39

8

Просто используйте std::stringstream:

#include <sstream> 
#include <iostream> 

using namespace std; 

int main() { 
    unsigned int x; 
    stringstream ss; 
    ss << hex << "ff"; 
    ss >> x; 
    // output it as a signed type 
    cout << static_cast<int>(x) << endl; 
} 

Вы также можете использоватьот прямой до C:

#include <cstdlib> 
#include <iostream> 

using namespace std; 

int main() { 
    string s = "ff"; 
    char *p; 
    long n = strtol(s.c_str(), &p, 16); 
    if (*p != 0) { 
     cout << "fail" << endl; 
    } 
    else { 
     cout << n << endl; 
    } 
} 
+0

Если это проблема, которая, скорее всего, будет распространена (разбор входных строк по номерам), почти наверняка есть библиотечная функция для ее обработки уже для вас. – jason

+1

'char * p; * key_num = strtol (& buff [140], & p, 16); 'работал - спасибо! – 2009-12-30 18:29:30

+0

@Roboto: Отлично, рад, что смогу помочь. – jason

1

Поскольку вы уже используете sscanf, то почему бы не иметь его разобрать шестнадцатеричные цифры для вас:

sscanf(buff, "%x %x", &val1, &val2); 
+0

& buf [140] выдается как/#, когда вы это делаете – 2009-12-30 18:20:57

Смежные вопросы