我有这种格式的文件:
F2,80,FF,CF,0F,00,A2,XXXX,XXXX,XXXX,01FE,00
我需要取字节3和4并将它们组合成有符号整数。
例如,我应该提取FF
和CF
并将它们合并到0xFFCF
。这应该给我一个有符号值的-49
。
我的代码在这里:
int main()
{
char buffer[1024] ;
char *record,*line;
uint8_t val;
uint8_t msb, lsb;
int16_t rate;
int i=0,j=0;
int mat[100][100];
FILE *fstream = fopen("log1.txt","r");
if(fstream == NULL)
{
printf("\n file opening failed ");
return -1 ;
}
while((line=fgets(buffer,sizeof(buffer),fstream))!=NULL)
{
record = strtok(line,",");
int count = 0;
while(record != NULL)
{
count++;
if (count == 3)
{
printf("string:%s\n", record);
sscanf(record, "%02X", &msb);
printf("MSB: %01X\n",msb) ;
}
if (count == 4)
{
printf("string:%s\n", record);
sscanf(record, "%02X", &lsb);
printf("lsb: %01X\n",lsb);
}
if (count == 5)
{
int16_t value = (short)(((msb) & 0xFF) << 8 | (lsb) & 0xFF);
printf("rate: %.2f\n", value*0.03125);
getchar();
}
record = strtok(NULL,",");
}
++i ;
}
return 0;
}
我从代码中看到的确切输出是:
string:FF
MSB: FF
string:CD
lsb: CD
HEX: 00CD
rate: 6.41
我希望率为:-1.59
我似乎从来没有看到负数,而且我得到的数值太小了。
答案 0 :(得分:1)
不是使用不同的变量类型来尝试获得你想要的行为,而是如何明确它呢?像这样:
#include <stdio.h>
int main(int argc, char *argv[])
{
int msb = 0xff;
int lsb = 0xcf;
int value = (((msb & 0xff) << 8) | (lsb & 0xff));
if (value >= 0x8000) value = -(0x10000 - value);
printf("%d\n", value);
return 0;
}
答案 1 :(得分:0)
以下是我如何使用代码:
int16_t hexToInt(char* msb, char* lsb)
{
char toparse[50];
strcpy(toparse, msb);
strcat(toparse,lsb);
int16_t number = (int16_t)strtol(toparse, NULL, 16);
return number;
}
int main()
{
char buffer[1024] ;
char *record,*line;
uint8_t val;
char msb[16], lsb[16];
int16_t rate;
FILE *fstream = fopen("log1.txt","r");
if(fstream == NULL)
{
printf("\n file opening failed ");
return -1 ;
}
while((line=fgets(buffer,sizeof(buffer),fstream))!=NULL)
{
record = strtok(line,",");
int count = 0;
while(record != NULL)
{
count++;
if (count == 3)
{
printf("string:%s\n", record);
strcpy(msb, record);
}
if (count == 4)
{
printf("string:%s\n", record);
strcpy(lsb,record);
}
if (count == 5)
{
int16_t value = hexToInt(msb,lsb);
printf("rate: %.2f\n", value*0.03125);
getchar();
}
record = strtok(NULL,",");
}
++i ;
}
return 0;
}
答案 2 :(得分:0)
该值确实是0xFFCF
,但是当与0.03125
相乘时,它会被提升为更高的数据类型,因为哪个值会丢失其签名。
只需更改
printf("rate: %.2f\n", value*0.03125);
到
printf("rate: %.2f\n", ((short)value*0.03125));
值为-49 or 0xFFCF
时输出为
rate: -1.53
答案 3 :(得分:0)
代码具有未定义的行为。 OP的代码尝试将int
大小的结果保存到1字节的位置。一个好的编译器或启用了警告的编译器会警告这个问题。
uint8_t msb, lsb;
...
sscanf(record, "%02X", &msb);
sscanf(record, "%02X", &lsb);
代码可以使用正确的scanf()
说明符
#include <inttypes.h>
sscanf(record, "%02" SCNx8, &msb);
sscanf(record, "%02" SCNx8, &lsb);
或只是一个不同的类型
unsigned msb, lsb;
...
sscanf(record, "%02X", &msb);
sscanf(record, "%02X", &lsb);
OP的转换是可疑的:
uint8_t msb, lsb;
int16_t value = (short)(((msb) & 0xFF) << 8 | (lsb) & 0xFF);
printf("rate: %.2f\n", value*0.03125);
建议类似@John Bickers的内容即使int
为16位,以下内容仍可正常工作。
long value = msb;
value <<= 8;
value += lsb;
if (value >= 0x8000) value -= 0x10000;
printf("value %ld\n", value);
// -49 * 0.03125 --> "-1.53"
printf("rate: %.2f\n", value * 0.03125);
由于OP预计从-49缩小到-15.6,可能需要按1 / pi缩放而不是* 0.03125
?