我的解析函数遇到了一些麻烦所以我在运行时把一些cout语句告诉我某些变量的值,我相信atoi错误地转换了字符。
下面是我的代码的一小部分,它的行为很奇怪:
c = data_file.get();
if (data_index == 50)
cout << "50 digit 0 = '" << c << "' number = " << atoi(&c) << endl;
此声明的输出是:
50 digit 0 = '5' number = 52
我在一个循环中调用这个代码,奇怪的是它正确地转换了前47个字符,然后在第48个字符上它在整数之后添加了0,在第49个字符上它添加了1,在50(在这里看到)它增加了两个,一直到第57个字符,它增加了9,然后它继续正确地转换到第239个字符。
这很奇怪还是什么?
为了澄清一点,我会发布整个功能。该函数传递一个指向空双数组(ping_data)的指针:
int parse_ping_data(double* ping_data)
{
ifstream data_file(DATA_FILE);
int pulled_digits [4];
int add_data;
int loop_count;
int data_index = 0;
for (char c = data_file.get(); !data_file.eof(); c = data_file.get())
{
if (c == 't' && data_file.get() == 'i' && data_file.get() == 'm' && data_file.get() == 'e' && data_file.get() == '=')
{
loop_count = 0;
c = data_file.get();
if (data_index == 50)
cout << "50 digit 0 = '" << c << "' number = " << atoi(&c) << endl;
pulled_digits[loop_count] = atoi(&c);
while ((c = data_file.get()) != 'm')
{
loop_count++;
if (data_index == 50)
cout << "50 digit " << loop_count << " = '" << c << "' number = " << atoi(&c) << endl;
pulled_digits[loop_count] = atoi(&c);
}
add_data = 0;
for (int i = 0; i <= loop_count; i++)
add_data += pulled_digits[loop_count - i] * (int)pow(10.0,i);
if (data_index == 50)
cout << "50 index = " << add_data << endl;
ping_data[data_index] = add_data;
data_index++;
if (data_index >= MAX_PING_DATA)
{
cout << "Error parsing data. Exceeded maximum allocated memory for ping data." << endl;
return MAX_PING_DATA;
}
}
}
data_file.close();
return data_index;
}
答案 0 :(得分:6)
atoi
接受一个字符串,即char
s的空终止数组,而不是指向单个char
的指针,因此这是不正确的,会使您获得不可预测的结果。
char c;
//...
/* ... */ atoi(&c) /* ... */
此外,atoi
没有提供任何方法来检测错误,因此更喜欢strtol
和类似的功能。
E.g。
char *endptr;
char c[2] = {0}; // initalize c to all zero
c[0] = data.file.get(); // c[1] is the null terminator
long l = strtol(c, &endptr, 10);
if (endptr == c)
// an error occured
答案 1 :(得分:3)
atoi
期望以null结尾的字符串作为输入。您提供的不是以null结尾的字符串。
话虽如此,总是值得补充的是,正确使用atoi
非常困难(如果可能的话)。 atoi
是一个不提供错误控制且没有溢出控制的函数。在C标准库中执行字符串表示到数字转换的唯一正确方法是来自strto...
组的函数。
实际上,如果你只需转换一个字符数字,使用atoi
或任何其他字符串转换功能是一种奇怪的矫枉过正。正如已经提出的那样,您只需从字符数字值中减去0
的值即可获得相应的数值。语言规范保证这是一个可移植的解决方案。
答案 2 :(得分:2)
没关系,只是我需要将字符转换为以\ 0结尾的字符串。我把它改成了这段代码:
char buffer [2];
buffer [1] ='\ 0';
buffer [0] = data_file.get();
if(data_index == 50)
cout << "50 digit 0 = '" << buffer[0] << "' number = " << atoi(buffer) << endl;
并且有效。