关于C语言下的atof的小问题

尼再采 发布于 2014/01/14 23:16
阅读 1K+
收藏 0
GCC

自从毕业之后,除了搞搞jni,基本上没写过C 程序了,最近又搞上jni了,可是,C语言还是有点儿忘记了。下面这段代码就是这样,不符合我的预期,一时不知道咋回事,麻烦给指出来一下问题出在哪里?

int main(int argc, char **argv) {
        char str_int[10] = "435";
        char str_float[30] = "432.44";
        char *s = "45.344 soft";

        int num_int = atoi(str_int);
        float num_float = atof(str_float);

        printf("num_int:%d. num_float:%f. test:%d. s:%f\n", num_int, num_float, atof("abcd"), atof(s));
}
gcc foo.c -o foo

然后运行,结果却如下:

怎么会打印出num_float,s 都是0呢?求教。。。

加载中
0
j
jucc

double atof(const char *);


int main(int argc, char **argv) { 

 char str_int[10] = "435"; 
 char str_float[30] = "432.44"; 
 char *s = "45.344 soft"; 

 int num_int = atoi(str_int); 
 float num_float = atof(str_float); 
 printf("num_int:%d. num_float:%f. test:%d. s:%f\n", num_int, num_float, atof("abcd"), atof(s)); 
}

这样修复运行正确,所以大神的解释对了

尼再采
好吧,我错了,这才是正确答案。关于解释请看本答作者的其他回答。 希望大家吸取教训,莫要犯同样的错误,不然这个坑就白填了。 感谢各位的支持和跟帖。 ~~~~~~~~ 剧 终 ~~~~~~~~~~
0
tsl0922
tsl0922

使用上貌似没什么问题吧,我的执行结果和你不一样?

tsl0922s-air:~ tsl0922$ gcc foo.c -o foo
foo.c:12:81: warning: format specifies type 'int' but the argument has type
      'double' [-Wformat]
  ...num_float:%f. test:%d. s:%f\n", num_int, num_float, atof("abcd"), atof(s));
                        ~~                               ^~~~~~~~~~~~
                        %f
1 warning generated.
tsl0922s-air:~ tsl0922$ ./foo 
num_int:435. num_float:432.440002. test:5. s:0.000000

tsl0922
tsl0922
回复 @尼再采 : 这里的结果就是已经引入stdio.h, stdlib.h两个头文件了的,mac下作的测试
尼再采
你的test和s结果也不正确。。。
0
娱乐你我
娱乐你我

printf("num_int:%d. num_float:%f. test:%d. s:%f\n", num_int, num_float,atoi("abcd"), (float)atof(s));

倒数第二个参数atoi,最后一个参数强制转成float试试。

尼再采
不行呢,按照你说的,结果是num_int:435, num_float:0.000000. test:0. s:0.000000 这依然不对啊
0
abinbin1
尼再采
哈哈,你的也不对。。。。又一种情况出现了
0
tsl0922
tsl0922

把1楼的那个warning处理下似乎结果就是对的了:

tsl0922s-air:~ tsl0922$ gcc foo.c -o foo
tsl0922s-air:~ tsl0922$ ./foo
num_int:435. num_float:432.440002. test:0.000000. s:45.344000

修改后代码:

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

int main(int argc, char **argv) {
        char str_int[10] = "435";
        char str_float[30] = "432.44";
        char *s = "45.344 soft";

        int num_int = atoi(str_int);
        float num_float = atof(str_float);

        printf("num_int:%d. num_float:%f. test:%f. s:%f\n", num_int, num_float, atof("abcd"), atof(s));
}
中山野鬼
中山野鬼
回复 @tsl0922 : %d ,%f的处理方法不同。atoi ,atof 这些函数是字符串转数值,有自己一套方法。printf是另一套方法。但反过来,是把数值转字符串。这个你man一下基本就出来了。哈。
tsl0922
tsl0922
回复 @中山野鬼 : 3楼就是这个回答里的代码,1楼就是最佳答案下面的那个,和这个回答里代码的区别只有test的格式化用的是%d
中山野鬼
中山野鬼
回复 @tsl0922 : 1楼,3楼是什么哈,貌似现在楼层混乱。
tsl0922
tsl0922
@中山野鬼 ,鬼哥给解释下1楼和3楼结果为什么会不同?
0
abinbin1
abinbin1
定义函数:double atof(const char *nptr);

函数说明:atof()会扫描参数nptr 字符串, 跳过前面的空格字符, 直到遇上数字或正负符号才开始做转换, 而再遇到非数字或字符串结束时('\0')才结束转换, 并将结果返回. 


0
liangdian
liangdian

转换是没有问题的,关键是出来printf输出上,倒数第二个指定类型不匹配,修改为:

printf("num_int:%d num_float:%f test:%d s:%f  \r\n", num_int, num_float, (int)(atof("abcd")), atof(s));

0
尼再采

不好意思,各位,你们都没猜对。

我来解释吧,一个群里的朋友告诉的,很简单,加上 stdio.h, stdlib.h两个头文件就正常了,猜测原因是:“未加头文件,可能使用了默认的方法或类型,加了头文件,有些方法可能重载了(补:可能是宏替换,C中木有重载)”(以上猜测未验证),但是效果确实出众,一下子搞定问题。

So, 有时候不关注别人的警告的话,你有可能会栽跟头。

谢谢观赏,本帖完。不好意思,分还是给自己好了。

(补:既然有些朋友不认同我这个答案,希望你们能够继续研究一下,争取把这个坑给彻底填平了,我精神上非常支持你们的做法,但是我没有时间参与一起研究,抱歉。今晚,我会来这里“收割”一下答案,如果有好的答案,我会改正。

娱乐你我
娱乐你我
回复 @尼再采 : 你换个平台试试,Linux也许没问题,试试Windows下vs或者其他硬件下位机上的程序。不是说智能的问题,类型最好匹配,这个是我要表达的意思。
尼再采
回复 @狼来了而已 : 那猜测可能是宏替换
尼再采
回复 @xuezhimeng : 如果你愿意深入研究这个问题,彻底把这个坑填平,我非常支持你这样的做法,只是,我无法抽出时间跟你一起研究,抱歉。
尼再采
回复 @xuezhimeng : 你的意思是说printf的打印不是那么智能是不?有可能前面出错会刷掉打印缓冲区导致错误的打印结果?我倒是没发现这样的现象,至少在这个问题上。不知道你是否是这个意思。 至于你说“我贴图只有执行结果。。。是否加头文件也只有我知道”,在这个问题上,我根本没必要撒这个谎,我是来求答案求原因的,肯定尊重事实。
尼再采
回复 @tsl0922 : 积分不积分的也就这么一说,不在乎这些的。
下一页
0
liangdian
liangdian
影响到后面的变量输出结果。
0
魔神翼
魔神翼
sscanf(str_int, "%d", &num_int);
sscanf(str_float, "%f", &num_float);



返回顶部
顶部