English 中文(简体)
为一个char数组分配内存,以连接一个已知的文本和一个整数。
原标题:Allocating memory for a char array to concatenate a known piece of text and an integer

我要将一个文本片段连接起来,比如“答案是”,加上一个有符号整数,得到输出“数字是42”。

我知道这段文本有多长(14个字符),但我不知道数字的字符串表示将有多少个字符。

我假设最坏的情况,最大的16位带符号整数有5个数字,再加上一个负号,所以以下代码是正确的吗?

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

int main()
{
    char *message;

    message = malloc(14*sizeof(char)+(sizeof(int)*5)+1);

    sprintf(message, "The answer is %d", 42);

    puts(message);

    free(message);
}
最佳回答

使用:

malloc(14*sizeof(char) /*for the 14 char text*/
       +(sizeof(char)*5) /*for the magnitude of the max number*/
       +1 /* for the sign of the number*/
       +1 /* for NULL char*/
      );

Since the digits will be represented as char you have to use sizeof(char) instead of sizeof(int).

问题回答

不完全是,您只需要一定数量的字符,因此不需要sizeof(int)

然而,为了易于维护和可移植的代码,你应该拥有类似于:

#define TEXT "The answer is "
#undef CHARS_PER_INT
#if INT_MAX == 32767
    #define CHARS_PER_INT 6
#endif
#if INT_MAX == 2147483647
    #define CHARS_PER_INT 11
#endif
#ifndef CHARS_PER_INT
    #error Suspect system, I have no idea how many chars to allocate for an int.
#endif

int main (void) {
    char *message;

    message = malloc(sizeof(TEXT)+CHARS_PER_INT+1);
    sprintf(message, TEXT "%d", 42);
    puts(message);
    free(message);
    return 0;
}

这有很多优点:

  • If you change the string, you change one thing and one thing only. The argument to malloc adjusts automatically.
  • The expression sizeof(TEXT)+CHARS_PER_INT+1 is calculated at compile time. A solution involving strlen would have a runtime cost.
  • If you try to compile your code on a system where integers may cause overflow, you ll be told about it (go fix the code).
  • You should actually allocate an extra character for the number since the biggest 16-bit number (in terms of character count) is -32768 (six characters long). You ll notice I still have a +1 on the end - that s because you need space for the string null terminator.

一个方法(不一定推荐)可以使用stdio函数本身来获得数字的字符确切大小。

例如,如果您在分配内存之前(出于任何原因)打印数字,您可以使用printf中的%n格式标识符。 %n不打印任何内容;相反,您提供它与int指针,printf将其填充为到目前为止已写入多少个字符。

另一个例子是snprintf,如果您有它可用。您将传递给它要写入字符串的最大字符数,然后它返回它应该写入的字符数,不包括最后的nul。(或错误时返回-1)。因此,使用一个1字节的虚拟字符串,snprintf可以精确地告诉您您的数字有多少个字符。

使用这些函数的一个巨大优点是,如果您决定更改数字格式(前导0,填充空格,八进制输出,长整形等),您将不会超出内存。

如果您有针对的GNU扩展,您可能需要考虑使用。 这与sprintf完全相同,只是它为您执行内存分配!不需要汇编。 (尽管您需要自己释放它。)但是您不应该依赖它具有可移植性。

malloc((14 + 6 + 1) * sizeof(char)); 的中文翻译是:分配 ((14 + 6 + 1) * sizeof(char)) 的内存空间。

  • 14 char for the string
  • 6 for de digits + sign
  • 1 for the

注意:Sizeof(int)返回类型的大小(以字节为单位)。如果 int 是32位,则Sizeof(int)==4,如果是64位,则为8。

我认为得到整数的十进制表示的最大长度的正确公式应为(floor(log10(INT_MAX))+1);您还可以滥用预处理器以此方式:

#include <limits.h>
#define TOSTRING_(x) #x
#define TOSTRING(x) TOSTRING_(x)
/* ... */
#define YOUR_MESSAGE "The answer is "
char message[]=YOUR_MESSAGE "+" TOSTRING(INT_MAX);
sprintf(message+sizeof(YOUR_MESSAGE),"%d", 42);

这也避免了堆分配。您可能想使用snprintf以获得更好的安全性,尽管使用此方法应该没有必要。

类似于这样的另一个技巧是创建一个像这样的函数:

size_t GetIntMaxLenght()
{
    const char dummy[]=TOSTRING(INT_MAX);
    return sizeof(dummy)+1;
}

如果编译器足够智能,它可以完全从编译代码中清除虚拟变量,否则宣布为静态变量以避免重新初始化每次函数调用可能是明智的。

有符号的 int 的安全近似值是(包括可能的 - 符号的位数):

(CHAR_BIT * sizeof(int) + 1) / 3 + 1

无符号的等价物是:

(CHAR_BIT * sizeof(unsigned) + 2) / 3

这个计算出数字的数量 - 如果分配空间用于以空终止的字符串,则将两个数字都加一来解释终止符。

这将稍微高估非常长的类型所需的空间(并且在int具有填充位的不寻常情况下也会高估),但是它是一个很好的近似值,并且具有编译时常量的优势。CHAR_BIT<limits.h>提供。





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签