一个浮点数在C中打印好,另一个不打印

时间:2017-01-27 14:07:42

标签: c printing floating-point

运行以下内容的结果:

struct drinks{
    float alcohol;
    float price;
    char name[1];
};

/*stackoverflow.com/questions/10162152/how-to-work-with-string-fields-in-a-c-struct*/

void main(){

    struct drinks cosmo;
    //The following:
    cosmo.alcohol = 20.67;
    //gives some crazy result when printed ! Says alcohol content is 2345826759803.00000000 (or any random number like that)
    cosmo.price = 10.0;
    char name[] = "Cosmopolitan";
    size_t length = strlen(name);
    realloc(cosmo.name,length);
    strcpy(cosmo.name, name);

    printf("The alcohol content of the %s is %4.2f, and it costs %2.f",cosmo.name, cosmo.alcohol, cosmo.price);
}

正是它应该是什么(饮料的名称和价格打印罚款!),除了饮料的酒精含量打印为荒谬的数字!

P.S。代码的主题是胡说八道,我只是学习并决定想出任何东西。

编辑:它奏效了!我用过简单的修复,谢谢!我现在可以问,并随时获取技术,为什么内存分配到" name"对打印饮料酒精含量的正确浮动值有什么影响?

3 个答案:

答案 0 :(得分:2)

你有一个字段name,它是一个大小为1的char数组。

你执行了realloc(cosmo.name,length);未定义的行为,这可以解释这些数字是“荒谬的”。

您的结构应该为字符串定义更大的尺寸

struct drinks{
float alcohol;
float price;
char name[100];};

或定义指针(将其设置为NULL,以便realloc正常工作,或使用malloc):

struct drinks{
float alcohol;
float price;
char *name;};

当你realloc/malloc时,不要忘记字符串终结符(+1)或使用strdup

cosmo.name = malloc(1+length);
strcpy(cosmo.name, name);

cosmo.name = strdup(name);

答案 1 :(得分:2)

有两个问题:第一个是结构name成员是一个数组,在编译时它的大小是固定的。你无法重新分配。调用realloc将导致未定义的行为

接下来的问题是你将一个长字符串复制到单个元素数组中,从而写出超出范围,再次有未定义的行为。

明显而简单的解决方案是创建具有更大尺寸的数组。您还可以将name成员转换为指针,在这种情况下,您可以为其分配内存(使用mallocstrdup)。如果您选择第二个解决方案并使用malloc,请记住C中的字符串有一个终止符。因此,像"hello"这样的字符串有六个元素:您看到的五个元素以及strlen加上终结符的数字。

答案 2 :(得分:1)

在现代C中执行此操作的正确方法是:

typedef struct {
    float alcohol;
    float price;
    char name[];
} drinks;

...

const char str NAME[] = "Cosmopolitan";
drinks* cosmo = malloc(sizeof(*cosmo) + sizeof(NAME));

cosmo->alcohol = 20.67f;
cosmo->price = 10.0f;
memcpy(cosmo->name, NAME, sizeof(NAME));
// (strcpy is fine too, but is slightly slower)

请注意,所有sizeof运算符调用都会使用null终结符,因为它们是C字符串。