strtol在c中没有给我一致的价值观。 strtol如何运作?

时间:2014-11-13 02:15:43

标签: c bit-manipulation strtol

我写过以下词法分析器。它适用于以下输入:c& 3& f,(3 | 6)& c,f ^ 1。然而,我得到的strtol结果并不一致。当我运行< 3 | 3时,它将十六进制3转换为十进制8作为前三个值,然后将其正确转换为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&amp; 3&amp; f和&lt; 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

正如你所看到的第一个&#34; TOKEN int&#34;第二个表达式的值应该是3,但它返回8.然后它正确地将3转换为3。有谁知道为什么会这样? strtol如何转换为十进制?

1 个答案:

答案 0 :(得分:1)

变化:

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

成:

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

(假设您只想处理一位数字)。

如果您在前一种情况下执行strtol(),那么它会期待一个C风格的字符串,而您所提供的内容并不能保证是空终止的。

所以可能发生的事情是,你的记忆中有38qstrotol(temp,NULL,16)会将其变成56,这将是,当和 - 使用15编辑,为您提供8