打印
[STM8]

国sscan()中用不到%d格式

[复制链接]
4207|15
手机看帖
扫描二维码
随时随地手机跟帖
楼主
gjz175|  楼主 | 2011-11-7 14:23 | 只看该作者 回帖奖励 |倒序浏览

IAR中用函数sscanf()的问题

static char SG[30];
  static char RxCounter = 0;
  char* ptr;

   ptr = SG;
   sscanf(ptr, "%d", &RxCounter);    // SG=“67 ”
   这样写说参数的格式不对。

    sscanf(ptr, "%d", &RxCounter);中的%d改为%s后,没有警告,可以在变量中保存'6'。
    在帮助文档中说明可以用%d的格式的,要怎样才能正确使用呢?

使用特权

评论回复
沙发
gjz175|  楼主 | 2011-11-7 14:26 | 只看该作者
补充:在option中Scanf formatting 已经选择为Full

使用特权

评论回复
板凳
gjz175|  楼主 | 2011-11-7 14:57 | 只看该作者
什么在IAR中,sscan()中用不到%d格式,用%s没问题?

使用特权

评论回复
地板
gjz175|  楼主 | 2011-11-7 14:57 | 只看该作者 |阅读模式
本帖最后由 gjz175 于 2011-11-7 16:46 编辑

为什么在IAR中,sscan()中用不到%d格式,用%s没问题?
5
gjz175|  楼主 | 2011-11-7 15:23 | 只看该作者
怎么都 只看不回啊?

使用特权

评论回复
6
gjz175|  楼主 | 2011-11-7 16:19 | 只看该作者
本帖最后由 gjz175 于 2011-11-7 16:54 编辑

以下程序,在TC中正常运行。在IAR中,警告参数不兼容,最后结果不正确。
warming[]:argument is incompatible with corresponding format string conversion
求大侠帮忙

   char SG[4];   
    char RxCounter = 0;
   char* ptr;
   SG[0]='1';
   SG[1]='1';
   SG[2]='3';
   SG[3]='d';
   ptr = SG;

   sscanf(ptr, "%d",&RxCounter);
    printf("RxCounter = %d.",RxCounter);

使用特权

评论回复
7
gjz175|  楼主 | 2011-11-7 16:21 | 只看该作者
以上程序,在TC中正常运行。在IAR中,警告参数不兼容,最后结果不正确。
求大侠帮忙

使用特权

评论回复
8
gjz175|  楼主 | 2011-11-7 17:05 | 只看该作者
自己顶。等待。。。

使用特权

评论回复
9
香水城| | 2011-11-7 17:05 | 只看该作者
把 & 去掉。

使用特权

评论回复
10
hgjinwei| | 2011-11-7 21:47 | 只看该作者
char RxCounter;
"%d",&RxCounter ?
不怕内存越界啊?

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
gjz175 + 1
11
pkat| | 2011-11-7 22:48 | 只看该作者
把 & 去掉试试

使用特权

评论回复
12
gjz175|  楼主 | 2011-11-8 08:49 | 只看该作者
把&去掉验证了,是不行的。help手册有说要加“&”,而且也有说支持%d的格式。
6楼的程序在TC上运行是正常的,即从字符串中读数,以十进制保存在RxCounter中。

使用特权

评论回复
13
hgjinwei| | 2011-11-8 13:21 | 只看该作者
你所说的在TC上运行正常,是否是以Debug模式编译的,下面这段代码在VS2005上测试。
问题出在 RxCounter 的类型上,RxCounter 为char 型,但scanf会将他认为是int型,
然后就内存越界了。
还有,printf("RxCounter = %d.",RxCounter); 在8位机中也有可能出错,原因一样,
不过是读越界。但32位机没有表现出异常,可能是传参方式造成的,没有仔细查看过。

IAR还挺强悍的啊,这样也报错,不错。

#include "stdint.h"
#include <stdio.h>


void mputs(int len,void *pdat)
{
    int i;
    unsigned char *sp = (unsigned char *)pdat;

    for(i=0; i<len; ){
        int tmp = *(sp+i);
        printf("%02X ",tmp);
        
        if(0 == (++i%8)){
            printf("\r\n");
        }
    }
}

int main(int argc, char *argv[])
{
    char    ch1 = 0x11;
    char    ch2 = 0x12;
    char    buff[4] = {0xA0,0xA1,0xA2,0xA3};

    struct {
        char    ch1;
        char    ch2;
        char    buff[4];
    }mm = {
        0x21,
        0x22,
        0xB0,0xB1,0xB2,0xB3
    };

    printf("\r\nroom ch1  @ 0x%08X : ",(unsigned long)&ch1);
    mputs(sizeof(int),&ch1);
    printf("\r\nroom ch2  @ 0x%08X : ",(unsigned long)&ch2);
    mputs(sizeof(int),&ch2);
    printf("\r\nroom buff @ 0x%08X : ",(unsigned long)&buff[0]);
    mputs(sizeof(int),&buff[0]);

    printf("\r\nroom mm   @ 0x%08X : ",(unsigned long)&mm);
    mputs(sizeof(mm),&mm);
    printf("\r\n");

    // 输入字符到ch1,因为编译器在分配空间时有可能强制了地址对齐,所以有可能不会影响到ch2
    // PS VS2005中在Debug模式编译时,ch1的输入不会干扰ch2,编译器预留了变量监测空间,但在
    // Release模式编译时,ch1的输入干扰了ch2。
    printf("input char to ch1 : ");
    scanf("%d",&ch1);

    // 输入字符到mm.ch1,因为我们已经限定了mm.ch1及mm.ch2的分布,且均为char格式,符合编译器
    // 的对齐要求,mm.ch2将受mm.ch1输入的干扰而变化。
    printf("input char to mm.ch1 : ");
    scanf("%d",&mm.ch1);

    printf("\r\nroom ch1  @ 0x%08X : ",(unsigned long)&ch1);
    mputs(sizeof(int),&ch1);
    printf("\r\nroom ch2  @ 0x%08X : ",(unsigned long)&ch2);
    mputs(sizeof(int),&ch2);
    printf("\r\nroom buff @ 0x%08X : ",(unsigned long)&buff[0]);
    mputs(sizeof(int),&buff[0]);

    printf("\r\nroom mm   @ 0x%08X : ",(unsigned long)&mm);
    mputs(sizeof(mm),&mm);
    printf("\r\n");

    getch();
}

使用特权

评论回复
14
gjz175|  楼主 | 2011-11-8 13:43 | 只看该作者
看你的回复之前,先谢你的详细解答。

使用特权

评论回复
15
gjz175|  楼主 | 2011-11-8 14:05 | 只看该作者
再谢谢你,因为问题解决了。
定义为int型后,问题就解决了。

使用特权

评论回复
16
gjz175|  楼主 | 2011-11-8 14:12 | 只看该作者
总结一下:

    函数的原型是:​​int sscanf(const char *restrict s, const char *restrict format, ...);


    函数printf("RxCounter = %d.",RxCounter);

  RxCounter定义的类型                  结果

    int8_t、uint8_t                    警告并不能运行

    int 、uint16_t                      无警告正确运行

    int16_t、int32_t、uint32_t   警告但能够正确运行


即RxCounter长度小于8位是不能正确运行的,hgjinwei说得对。谢谢hgjinwei的详细解答

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

45

帖子

1

粉丝