-2

私は次の字句解析器を書きました。c&3&f、(3|6)&c、f^1 などの入力に対して正しく機能します。ただし、strtol の結果は一貫していません。<3|3 を実行すると、最初の 3 つの値で 16 進数の 3 が 10 進数の 8 に変換され、2 番目の値で正しく 3 に変換されます。これが私のプログラム全体です。問題は最後の関数にあります。コードをデバッグするために printf を追加しました。(テキスト ファイルを stdin < に渡して実行します。各行の新しい式)

コードは次の場所にもあります: Github

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//Max number of characters on new line from file
#define LINE_MAX 1028

char expression[LINE_MAX];
int position;

char next();
char peek();
int E();
int EE(int i);
int A();
int AA(int i);
int B();
int BB(int i);
int C();

int main ( int argc, char *argv[] )
{
    char line[LINE_MAX];

    while (fgets(line, LINE_MAX, stdin) != NULL) {

        //remove the newline character for printing the expression
        size_t strlength = strlen(line);
        line[strlength-1] = '\0';

        //reset global variables
        position = 0;
        strcpy(expression, line);

        int result = E();

        printf("%s =  %x\n", line, result);
    }
}

char next(){
    return expression[position++];
}

char peek(){
    return expression[position];
}

int E(){
    int st = A();
    return EE(st);
}

//bitwise "|" OR
int EE(int i){
    char token = peek();

    if (token == '|'){ 
        next();
        int val = A();
        return EE(i | val);
    }else{
        return i; 
    }
}

int A(){
    int st = B();
    return AA(st);
}

//bitwise "^" XOR
int AA(int i){
    char token = peek();

    if (token == '^'){ 
        next();
        int val = B();
        return AA(i ^ val);
    }else{
        return i; 
    }
}

int B(){
    int st = C();
    return BB(st);
}

//bitwise "&" AND
int BB(int i){
    char token = peek();

    if (token == '&'){ 
        next();
        int val = C();
        return BB(i & val);
    }else{
        return i; 
    }
}

/*********************************************************************
 *********************************************************************
 This is the function I am having a problem with. Strtol is giving me 
 inconsistent integer values.
 *********************************************************************
 *********************************************************************/
int C(){ 

    char token = next(); 

    if(token == '<'){
        //bitwise shift secondToken <<
        printf("BITEWISE LEFT SHIFT: %c\n", token);
        return (C() << 1) & 15; //0xf;
    }else if(token == '>'){
        //bitwise shift secondToken >>
        return C() >> 1;
    }else if(token == '~'){
        //bitwise not secondToken ~
        printf("BITEWISE NOT: %c\n", token);
        return (~C()) & 15;
    }else if(token == '('){
        int val = E();
        next();
        return val; 
    }else{
        printf("TOKEN: %c\n", token);
        //return the token hex value as int
        char temp[1];
        temp[0] = token;
        printf("TEMP 0: %c\n", temp[0]);
        printf("TOKEN int: %d\n", (int)strtol(temp, NULL, 16) & 15);
        return (int)(strtol(temp, NULL, 16) & 15); //0xf;
    }
}

c&3&f および <3|3 に対して実行した結果は次のとおりです。

TOKEN: c
TEMP 0: c
TOKEN int: 12
TOKEN: 3
TEMP 0: 3
TOKEN int: 3
TOKEN: f
TEMP 0: f
TOKEN int: 15
c&3&f  =  0

BITEWISE LEFT SHIFT: <
TOKEN: 3
TEMP 0: 3
TOKEN int: 8
TOKEN: 3
TEMP 0: 3
TOKEN int: 3
<3|3  =  3

ご覧のとおり、2 番目の式の最初の "TOKEN int" 値は 3 である必要がありますが、8 が返されます。その後、3 が 3 に正しく変換されます。なぜこれが起こっているのか誰にも分かりますか?strtol はどのように 10 進数に変換されますか?

4

1 に答える 1

1

変化する:

char temp[1];
temp[0] = token;

の中へ:

char temp[2];
temp[0] = token;
temp[1] = '\0';

(1桁の数字のみを処理したい場合)。

strtol()前者の場合は、C スタイルの文字列が想定されており、指定したものが null で終わることが保証されていません。

おそらく起こっていることは、あなたの記憶には次のようなものが38qあり、それstrotol(temp,NULL,16)を に変換し56、 で and-ed すると15、 が得られるということです8

于 2014-11-13T02:34:58.363 に答える