2012-05-08 3 views
2

У меня есть программа, и я хочу взять аргумент командной строки из МАС-адрес, как "./myapp 00:11:22:33:44:55"C++ как преобразовать мой аргумент командной строки (MAC Address) для беззнаковых символов

Позже МАС-адрес используется для struct sockaddr_ll.sll_addr в массиве unsigned char каждый элемент представляет собой один октет MAC-адреса. Эта функция (найденная в блоге) принимает аргумент командной строки и разделяет ее, используя двоеточие «:» в качестве разделителя;

void StringExplode(string str, string separator, vector<string>* results){ 
    int found; 
    found = str.find_first_of(separator); 
    while(found != string::npos){ 
     if(found > 0){ 
      results->push_back(str.substr(0,found)); 
     } 
     str = str.substr(found+1); 
     found = str.find_first_of(separator); 
    } 
    if(str.length() > 0){ 
     results->push_back(str); 
    } 
} 

Мой код, принимающий аргумент командной строки, выглядит следующим образом;

unsigned char MAC[6]; 
vector<string> R; 
string thisstring = argv[2]; 
StringExplode(thisstring, ":", &R); 
MAC[0] = (unsigned char)atoi(R[0].c_str()); 
MAC[1] = (unsigned char)atoi(R[1].c_str()); 
MAC[2] = (unsigned char)atoi(R[2].c_str()); 
MAC[3] = (unsigned char)atoi(R[3].c_str()); 
MAC[4] = (unsigned char)atoi(R[4].c_str()); 
MAC[5] = (unsigned char)atoi(R[5].c_str()); 
printf("Ethernet %02x:%02x:%02x:%02x:%02x:%02x\n",MAC[0],MAC[1],MAC[2],MAC[3],MAC[4], MAC[5]); 

Однако это печатает «Ethernet 00: 0b: 16: 21: 2c: 37». Это потому, что atoi() обертывается? Кажется, я не могу указать на эту проблему, однако, я считаю, что это, вероятно, плохой способ сделать что-то. Я новичок в C++, но даже для меня это кажется длинным, поэтому я ожидаю, что кто-то из клавишных heros здесь сможет объяснить, насколько это плохо, и, надеюсь, как я мог бы сделать это более эффективным.

спасибо.

+3

Нет, это потому, что вы разбираетесь как десятичные, а не шестнадцатеричные. – Rup

ответ

3

Проблема заключается в том, что вы разбираете октетов в виде десятичных чисел не гекса - 11 = 0xB, 22 = 0x16 и т.д.

Я не уверен, что, как большинство C++ делать это, но вы можете, например, использовать strtoul с основным аргументом:

for(int i = 0; (i < 6) && (i < R.size()); ++i) { 
    MAC[i] = (unsigned char)strtoul(R[i].c_str(), NULL, 16); 
} 
+0

Спасибо Rup, я правильно ответил на ваш ответ, потому что вы также дали аккуратный маленький способ убрать это, так как я хочу, чтобы шестнадцатеричные значения не десятичные , Большое спасибо: D – jwbensley

1

С моей точки зрения все в порядке. Единственное, что вы печатаете десятичные значения в шестнадцатеричном представлении. Преобразование входных значений в шестнадцатеричный.

+0

Yeap, я сказал вам, что я новичок в C++, что за глупая ошибка: – jwbensley

2

Проблема заключается в том, что вы читаете в строках, представляющих шестнадцатеричные числа, как если бы они были десятичными. C++ 11 строки в целое функция преобразования имеет параметр, где можно указать основание ввода, поэтому для преобразования шестнадцатеричной строки в целое число без знака вы можете сделать это:

unsigned int i2 = std::stoi("ff", nullptr, 16); // input is base 16 

stoul, stoull, stol, stoi См.