2

プログラムがあり、次のような MAC アドレスのコマンド ライン引数を取得したい"./myapp 00:11:22:33:44:55"

その後、MAC アドレスはstruct sockaddr_ll.sll_addrunsigned char 配列で使用され、各要素は MAC アドレスの 1 オクテットになります。この関数 (ブログにある) は、コマンド ライン引数を受け取り、区切り文字としてコロン ":" を使用して区切ります。

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++ を初めて使用しますが、私にとってもこれは長く感じられるので、ここのキーボード ヒーローの誰かがそれがどれほど悪いかを説明できることを期待しています。

ありがとうございました。

4

3 に答える 3

3

問題は、オクテットを16進数ではなく10進数として解析していることです-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);
}
于 2012-05-08T09:51:36.013 に答える
2

問題は、16 進数を表す文字列を 10 進数のように読み取っていることです。C++11 文字列から整数への変換関数には、入力の基数を指定できるパラメーターがあるため、16 進文字列を符号なし整数に変換するには、次のようにします。

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

stoul、stoul、stol、stoiを参照してください。

于 2012-05-08T10:11:46.583 に答える
1

私の観点からは、すべて問題ありません。唯一のポイントは、16 進表示で 10 進値を出力していることです。入力値を 16 進数に変換します。

于 2012-05-08T09:50:30.167 に答える