atof создает странный результат
Я пытаюсь использовать atof() для преобразования строки в двойную (очевидно), но результаты не те, что я ожидаю. Вот код и отладочная информация о значениях переменных ДО 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
1 ответ
Ваша проблема, вероятно, вызвана get_next_string()
функция, возвращающая указатель на временный локальный массив символов. Как только функция возвращается, стековая память когда-то использовалась str[]
перезаписывается другой автоматической переменной. Это объясняет, почему arg
развращается.
Есть несколько возможных исправлений.
- Вызывающая сторона может выделить память для хранения строки и передать этот указатель функции для ее заполнения данными.
- Вызываемый может выделить память для строки и вернуть этот указатель. Это также возвращает право собственности на вызывающего абонента и ответственность за вызов
free()
когда сделано. str[]
массив может быть объявленstatic
внутри функции. Это больше не будет временным, но помните, что каждый раз, когда вы вызываете функцию, предыдущая строка будет перезаписываться.