-1

atof() を使用して文字列を double に変換しようとしていますが (明らかに)、結果は期待したものではありません。atof() の前の変数値に関するコードとデバッグ情報は次のとおりです。

d = atof (arg);
next.db = d;

*debug info*
arg = 0x0034f7b0 "10.0"
d = 0.0000000000000000

プログラムが atof() をステップ実行したら。結果は次のとおりです。

arg = 0x0034f7b0 "ôþSÄ÷4"
d = 0.0000000000000000

ご覧のとおり、コマンドの前に、arg 変数は有効な double を保持しています。ただし、戻り値は 0 です。なぜ arg の値が変わるのでしょうか?

また、stdlib.h が含まれています。同様に、arg は次のように宣言されます。

char *arg;

それがまったく役立つ場合、「10.0」はファイルから読み取られました。

より多くのコード:

void read_instructions()
{
    char *str;
    char *arg;
    int n;
    char c;
    double d = 0;
    instruction next = {0};

    while (!feof(datafile)) {
        // Fetch the next string
        // if (push or pop), get the next argument
        // create instructiwn and add to instruction array
        str = get_next_string();

        if (strncmp (str, "P", 1) == 0) {
            if (strncmp (str, "PUSH", 4) == 0) {
                next.func = pushFunc;
            }
            else {
                next.func = popFunc;
            }
            arg = get_next_string();
            n = arg[0];
            if (n > 64 && n < 71)
                next.ch = arg[0];
            else {
                d = atof (arg);
                next.db = d;
            }
            instr[instr_count] = next;
            instr_count++;
        }
    else {
        c = str[0];


        switch (c) {
        case 'A' :
            next.func = addFunc;
            break;
        case 'S' :
            next.func = subFunc;
            break;
        case 'M' :
            next.func = multFunc;
            break;
        case 'D' :
            next.func = divFunc;
            break;
        case 'H' :
            next.func = haltFunc;
        default :
            printf ("Invalid instruction");
        }
        instr[instr_count] = next;
        instr_count++;
    }
}
fclose (datafile);
}

これは、ファイルを開いてアクセスするための指定されたコードです。

FILE *datafile;


int main(int argc, char *argv[]) 
{
    if (argc != 2) {
        printf("error, incorrect number of arguments");
        haltFunc(instr[0]);
    }

    open_file(argv[1]);
    read_instructions();
    execute_instructions();
    return 0;
}

void open_file(char* argv) 
{
    char buf[1024];
    char cwd[512];

    getcwd(cwd, sizeof cwd);
    sprintf(buf, "%s\\%s", cwd, argv);

    if (!(datafile = fopen(buf, "r"))) {
        printf("Error: Make sure your file is located here:\n%s", buf);
    }
}

char* get_next_string() 
{
    char str[15];

    fscanf(datafile, "%s", &str);

    return str;
}

ヘッダー ファイル:

#ifndef MAIN_HEADER_H
#define MAIN_HEADER_H

#define INSTR_SIZE 30

typedef struct {
    void (*func)(instruction);
    union {
        double db;
        char ch;
    };
} instruction;

int main(int, char*);
char* get_next_string();
void open_file(char*);
void read_instructions();
void execute_instructions();
void pushFunc(instruction instr);
void popFunc(instruction instr);
void addFunc(instruction instr);
void subFunc(instruction instr);
void multFunc(instruction instr);
void divFunc(instruction instr);
void haltFunc(instruction instr);

#endif

そして、これはテストファイルです:

PUSH 10.0
PUSH 4.0
PUSH 7.0
PUSH 5.0
POP D
POP E
POP 
PUSH D
ADD
PUSH 5.0
POP B
PUSH 17.0
POP E
PUSH B
PUSH E
SUB
HALT
4

1 に答える 1

2

あなたの問題はおそらく一時的なローカル文字配列get_next_string()へのポインターを返す関数によって引き起こされます。関数が戻るとすぐに、一度使用されたスタック メモリは、他の自動変数によって上書きされます。それは、なぜ破損しているのかを説明します。str[]arg

いくつかの可能な修正があります。

  • 呼び出し元は、文字列を保持するためにメモリを割り当て、このポインタを関数に渡して、データで埋めることができます。
  • 呼び出し先は、文字列にメモリを割り当て、そのポインターを返すことができます。これにより、呼び出し元に所有権が返され、完了時に呼び出しの責任が返さfree()れます。
  • 配列は関数内str[]で宣言できますstatic。一時的なものではなくなりますが、関数を呼び出すたびに前の文字列が上書きされることに注意してください。
于 2012-07-11T15:14:30.090 に答える