1

以下是我打印 char 值的 C 代码,但我得到了意想不到的结果。代码是

#include<stdio.h>

main()
{

  char sendBuffer[1000];
  float count;
  int i;
  for(count=1.5;count<=2.5;)
  {
   for(i=0;i<=15;)
   {
     sendBuffer[0]=count+48;
     sendBuffer[1]='a';
     sendBuffer[2]='b';
     sendBuffer[3]='c';
     sendBuffer[4]=i+48;
     sendBuffer[5]='\0';
     printf("%s\n",sendBuffer);
     i=i+5;
    }
   count=count+0.5;
  }
}

我得到的结果是:

1abc0
1abc5
1abc:
1abc?
2abc0
2abc5
2abc:
2abc?
2abc0
2abc5
2abc:
2abc?

然而,我期待类似的东西

1.5abc0
1.5abc5
1.5abc10
1.5abc15 

等等。谁能告诉我如何在 C 中的 char 数组中存储整数和浮点值?

4

3 回答 3

8

我看到你得到的答案回答了这个问题,但没有给出解释,从它的外观来看,你可以使用一个很好的解释,所以这就是正在发生的事情:

C中的类型

您需要了解不同的类型(int, char, float, double)在内存中占用不同的大小。在 C 中,achar总是被认为占用一个字节,并且在 -127 到 128 的范围内。(unsigned char从 0 到 255。) ints 占用 4 个字节,它们的范围是从 -2M 到 2M - 1 . float分别double占用 4 和 8 个字节,范围很大,但精度有限。(有关更多信息,只需搜索“c type range”,您会发现很多信息,包括 Stack Overflow 上的这些链接,这些链接也为您提供了很好的解释:Definition of a range of a data type , Guarantateed minimum size/range C 数据类型)。

此外,您知道足够的 ascii 以知道将 48 添加到一个数字以获得 char 版本,但请确保您附近有一个 ascii 表。方便的是,您可以在http://www.asciitable.com找到一个。

您还必须了解编译器将尽最大努力从一个转换为另一个,但在某些情况下,例如将 afloat转换为 an int,如果您不明确执行此操作,您的编译器至少应该发出警告。

字符串在 C 中不作为类型存在。相反,您打印到数组中。其他答案告诉你如何做到这一点。他们的代码正在做的是将您想要的值打印到字符数组中,这就是您所需要的。

你的代码在做什么

现在,让我们看看您当前的代码在做什么:

首先,一个快速的侧边栏:当你做一个for循环时,最好把增量放在循环本身,所以:

for(count=1.5;count<=2.5;count=count+0.5)
{
  for(i=0;i<=15;i=i+5)

会更规范。

现在,您的第一行是sendBuffer[0]=count+48;. 这是发生的事情:

  1. 您正在计数,从 1.5 开始,再加上 48,所以第一个数字是 49.5。
  2. 编译器会自动将 a 更改float为 an int,尽管它应该给你一个警告。它通过截断值来实现,将 49.5 更改为 45。
  3. 然后它会更改(int)49(char)49相同的值,但占用一个字节而不是 4。Ascii 49 是“1”,所以这恰好是您想要的数字。
  4. 编译器对浮点的其余部分不做任何事情它从不为此值设置 sendBuffer[1] 或 [2]。

接下来的 3 行将字符串的第二个、第三个和第四个字符硬编码为abc. 即使您的第一行已将完整的浮点值设置为sendBuffer,这也会覆盖它。

您的最后一行将 i 取为 0、5、10 和 15,并将其添加到 48。这就像第一步一样,没有截断 from float。因此,它首先查找 ascii 48,即“0”,然后查找 ascii 53,即“5”。当i为 10 时,它现在采用 int 58 并将其转换为字符(再次将其从 4 个字节更改为 1 个字节)。打印 ascii 58 得到 ':',打印 ascii 63 得到 '?'。这就是你的输出结果如何。

可能的解决方案

最后,对您给出的解决方案说几句话:

由于您所做的只是输出结果,因此您不需要sendBuffer也不snprintf. 只需使用

printf("%.1fabc%d\n", count, i);

就足够了。

不过,想想 printf 系列函数的作用是有启发性的。虽然效率较低,但让我们用几个snprintfs 来看看它在做什么:

int index = 0;
index = snprintf(&sendbuf[index], sizeof(sendbuf) - index, "%.1f", count);
index += snprintf(&sendbuf[index], sizeof(sendbuf) - index, "abc");
index += snprintf(&sendbuf[index], sizeof(sendbuf) - index, "%d", i);
sendbuf[index++] = '\n';
sendbuf[index] = '\0';

当你传递多个参数时,它的作用是*printf:跟踪你写了多少,并用它来告诉你在哪里写下一部分。

如果你不知道,a += b语法是a = a + b. a++意思是“给我 a 的值,然后增加它”。

所以我的代码的第二行会将浮点值打印到 sendbuf 中,从 0 位置开始。 *printf总是返回打印的字符数,所以在这个例子中,它总是打印 3 个字符,我设置index为 3。

下一行将字符串 abc 写入 sendbuf,从位置 3 开始,之后的行将值打印i到位置 6。最后,我为新行添加 \n,最后一行是空终止符。我不放index++是因为我不再关心索引,所以不需要费心增加它。我把\0(和你上面一样)而不是 0,只是因为\0提醒程序员我们正在处理一个 char 数组,而不是一个整数数组。

同样,所有这些行都不是必需的,但由于某些问题似乎是理解什么printf,我认为这会有所帮助。

于 2013-07-25T14:30:58.500 回答
5

这可以工作:

snprintf(sendbuf, sizeof(sendbuf), "%.1fabc%d", count, i);
于 2013-07-25T14:07:38.597 回答
1

向输出数组添加一个字节。第一个元素需要 3 个字符(字节)而不是一个。

sprintf(sendBuffer,"%0.1f",count);
sendBuffer[3] = 'a';
....
于 2013-07-25T14:08:33.593 回答