【问题标题】:The printf functions print something that shouldn't, why?printf 函数会打印一些不应该打印的东西,为什么?
【发布时间】:2013-05-04 15:31:42
【问题描述】:

从下面的图片中可以看出,添加列表顶部的第二个元素会为 printf 函数创建一个奇怪的行为。

添加列表节点的功能是:

void add_QUEUEnode_top(Item a)
{
    if (head==NULL)
    {
        QUEUEinit(a);
    }
    else
    {
        QUEUEput_top(a);
    }
    return;
}

void QUEUEinit(Item a)
{
    head=(link)malloc(sizeof(link*));
    head->next=NULL;
    head->item=a;
    tail=head;
    printf("Coda iniziallizata...\n\n");

}

void QUEUEput_top(Item a)
{
    link tmp;
    tmp=(link)malloc(sizeof(link*));
    tmp->item=a;
    tmp->next=head;
    head=tmp;
    return;
}

这里是处理项目的函数:

Item fill_item()
{
    Item a;
    int i;
    for(i=0; i<DIM-1; i++)
    {
        a.stringa[i]=rand();
    }
    a.stringa[DIM-1]='\0';
    a.numero=rand();
    printf("\nOggetto generato: \n");
    print_item(a);
    return a;
}

void print_item(Item a)
{
    printf("\nStringa elemento: ");
    printf("%s", a.stringa);
    printf("\nNumero elemento:  %d\n", a.numero);
}

Here 是我正在编辑的代码块项目的链接。调用“bugged” printf 的函数print_item(Item a) 位于item.c 模块中,而生成列表项的函数位于list.c 模块中。

知道什么会导致这个问题吗?

PS:对于位于意大利语的捕获感到抱歉

编辑:项目的定义:

typedef struct
{
    char stringa[DIM];
    int numero;
} Item;

链接指针的定义:

typedef struct QUEUEnode *link;

链接结构的定义:

struct QUEUEnode
    {
        Item item;
        link next;
    };

【问题讨论】:

  • linkItem的定义是什么?我会注意到看起来像head=(link)malloc(sizeof(link*)); 的行是可疑的。投射到与您使用的尺寸不同的类型?实际上,在 C 中甚至根本不需要演员阵容,但你需要做一个疯狂的演员这一事实更有说服力....
  • 首先,malloc(sizeof(link*)) 行并没有分配您认为的内容。它为指针分配了足够的内存(即 4 或 8 个字节),这很可能不足以满足您的 link 结构。

标签: c printf


【解决方案1】:

您有几个错误 - 我会尝试为您找到更多错误,但您询问的具体问题与此代码有关:

for(i=0; i<DIM-1; i++)
{
    a.stringa[i]=rand();
}
a.stringa[DIM-1]='\0';

您只是在每个字符中放置一个随机数 - 其中许多可能不是您的字符集中的有趣字符,甚至是可打印字符。这就是为什么你会得到你所看到的疯狂输出。如果您想将随机可打印字符放入字符串中,请以更能识别字符集的方式进行。

还有一些问题:

  1. 这些分配行是错误的:

    head=(link)malloc(sizeof(link*));
    tmp=(link)malloc(sizeof(link*));
    

    他们应该是:

    head = malloc(sizeof(struct QUEUEnode));
    tmp = malloc(sizeof(struct QUEUEnode));
    

    也就是说,您应该为整个struct QUEUEnode 分配足够的大小,而不仅仅是指向一个的指针。 (或者指向一个指针的指针,这就是你所拥有的)。像使用 typedef struct QUEUEnode *link; 一样将指针类型隐藏在 typedef 中是有争议的样式选择之一 - 我个人不喜欢这样做,因为它很快就会混淆像这样的问题。

  2. 您在此程序中按值传递了许多结构。这很好,有效的 C,只是有点不习惯。通常人们会传递指针。如果您的结构增长到任何可察觉的大小,性能可能会因为所有隐式内存复制的进行而开始受到严重影响。

【讨论】:

  • 哦,如果我将 rand() 除以 ASCII 最大项?
  • 不,那也行不通。字符串中有很多您可能不想要的 ASCII 字符。
  • 好吧,我只是想要一些东西来填充那个字符串,这是一个大学练习;如何在仅有的字母数字 ASCII 字符之间生成随机数?
  • 检查 ASCII 表 - 您需要在 4857 之间的数字,在 6590 之间的大写字母,以及在 97122 之间的随机数对于小写字母。我想您可以通过某种算法直接生成它们,或者您可以使用isalnum() 简单地丢弃坏的。不过,我不确定这是一个很好的解决方案。
  • ... 或者更好,head = malloc(sizeof *head);
【解决方案2】:

您将随机文本分配给stringa,然后将numero 设置为一个随机数。当您打印这些东西时,您会得到随机输出。因为您没有将随机化限制为可打印字符,所以会发生奇怪的事情。您正在打印控制字符。您的第二个屏幕截图表明您打印了一个carriage return 字符。我确定你不想那样做!

程序正在按照您的要求执行。因为你没有说你想从哪个字符集分配给stringa,所以我真的不能说你的程序应该是什么。您可以通过此更改使其选择 A 到 Z 范围内的值:

a.stringa[i] = 'A' + rand() % 26;

我敢打赌,您的代码还有其他问题,但由于问题的主要焦点与打印有关,我不会再深入研究。

【讨论】:

  • 是的,但是看看第二张图片在生成字符串之前发生了什么!
  • @LambertoBasti,这可能是因为您在该字符串中随机生成了一个回车符。
  • 那只是非打印字符。可能是 CR 字符。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-30
  • 2014-07-03
  • 1970-01-01
  • 2021-10-23
  • 2018-06-24
  • 2015-08-23
  • 2011-05-27
相关资源
最近更新 更多