0

私はシステムの古いcコードでバグ修正を行っています(奇妙なことに、それは標準のcではありません。gccによってコンパイルされていません)。文字列をunsignedchar形式のバイナリコードに変換しているように見えるこのコードにたどり着きました。ロジックパズル私(太字部分)。これはあなたたちにとって意味がありますか?

これをコピーして、長さが13ではなく11の別の文字列で再利用する必要があるため、このコードを理解する必要があります。

char l_call_dest_no[25];
int l_loop_cnt;
unsigned char l_bcd_byte;
unsigned char l_call_dest_no_in_bcd[13];

...some other code as input...

    for (l_loop_cnt = 0; l_loop_cnt < 13; l_loop_cnt++)
            {
                l_bcd_byte = '\0';
                switch (l_call_dest_no[l_loop_cnt * 2])
                {
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                    case '8':
                    case '9':
                        l_bcd_byte = (l_call_dest_no[l_loop_cnt * 2] - 48) * 16;
                        break;
                    case 'A':
                        l_bcd_byte = 10 * 16;
                        break;
                    case 'B':
                        l_bcd_byte = 11 * 16;
                        break;
                    case 'C':
                        l_bcd_byte = 12 * 16;
                        break;
                    case 'D':
                        l_bcd_byte = 13 * 16;
                        break;
                    case 'E':
                        l_bcd_byte = 14 * 16;
                        break;
                    case 'F':
                    case ' ':
                        l_bcd_byte = 15 * 16;
                        break;
                    default:
                        printf("*** invalid call destination number ***\n");
                        return_status = FAILURE;
                        break;
                }

                if (l_loop_cnt < 12)
                {
                    switch (l_call_dest_no[l_loop_cnt * 2 + 1])
                    {
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                        case '8':
                        case '9':
                            l_bcd_byte = l_bcd_byte + (l_call_dest_no[l_loop_cnt * 2 + 1] - 48) ;
                            break;
                        case 'A':
                            l_bcd_byte = l_bcd_byte + 10;
                            break;
                        case 'B':
                            l_bcd_byte = l_bcd_byte + 11;
                            break;
                        case 'C':
                            l_bcd_byte = l_bcd_byte + 12;
                            break;
                        case 'D':
                            l_bcd_byte = l_bcd_byte + 13;
                            break;
                        case 'E':
                            l_bcd_byte = l_bcd_byte + 14;
                            break;
                        case 'F':
                        case ' ':
                            l_bcd_byte = l_bcd_byte + 15;
                            break;
                        default:
                            printf("*** invalid call destination number ***\n");
                            return_status = FAILURE;
                            break;
                    }
                }
                else
                    l_bcd_byte = l_bcd_byte + 15;

                if (l_bcd_byte == 255)
                    l_call_dest_no_in_bcd[l_loop_cnt] = '\0';
                else
                {
                    l_call_dest_no_in_bcd[l_loop_cnt] = l_bcd_byte;
                        l_call_dest_no_bcd_length++;
                }
            }   
4

2 に答える 2

4

このコードは、16進数(eg "002A40FF160AD")を含む文字列を生のバイナリ(eg)の値を含むバイトの配列に変換します{0x00, 0x2A, 0x40, 0xFF, 0x16, 0x0A, 0xDF}。この関数にはいくつかの落とし穴があります。

  • 不思議なことに、文字列の長さは均一ではないため、追加の「F」が文字列の最後にあることを意味します。(else l_bcd_byte = l_bcd_byte + 15;)。
  • 追加の奇妙な点は"FF"、0x00に変換されることです。
  • 'F'' '(スペース)の両方が'F'
  • この関数は、文字列からパック10進数(BCD)へのコンバーターとしても機能します。これは、パック10進数が0〜9の数字のみを使用する16進数のように見えるためです(たとえば、10進数の15は0x15パック10進数です)。ただし、ファイナルFはこの機能を複雑にします。

編集

最後のFは、パック10進数形式を実際に使いやすくします。パック10進数の末尾にあるFは、その数値が符号なしであることを意味します。

于 2012-08-03T07:30:46.430 に答える
1

これはカスタムBCDトランスです。BCD形式を調べて、数値をBCD形式から通常の数値に変換する方法をよく理解してください。

その後、古いコードを移行する場合は、関数内のコードブロック全体を移動するようにしてください。バグがあっても。古いコードはそのバグに依存している可能性があります。古いコードにつながるすべてのコードパスがカバーされ、バグがないことを証明した後、動作の修正/変更を開始できます。

質問が1つありますが、なぜ標準のCコードではないのですか?gccがそのコードであなたに与えるエラーは何ですか?-std =引数はどのように見えますか?(私はあなたの投稿に返信することでそれを求めたでしょうが、どうやら私は許可されていません。)

于 2012-08-03T08:25:32.157 に答える