【问题标题】:Using printf on an array of chars returns garbage and string在字符数组上使用 printf 会返回垃圾和字符串
【发布时间】:2012-10-31 10:11:18
【问题描述】:

我正在尝试使用 printf 在名为 point_person 的指针内打印出一个字符数组,当我使用它来返回用户的名字时,它会打印出很多垃圾,然后最后打印出名称。

代码看起来像这样:

    person dequeue_person;
    person *point_person = &dequeue_person;
    get_person(point_person, 9);
    printf("%s", point_person->first_name);

person 是一个 typedef 结构,包含 3 个字符变量:first_name[64]、last_name[64]、pes_nbr[64]。

输出如下:

F÷rn:约翰 ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠约翰

这是什么原因造成的,以后如何避免这种情况?

编辑: 填充 first_name 的代码如下所示:

void get_person(person *pers, int index)
{
    person per_son;

    strcpy(per_son.first_name, queue[(index+head)%QUEUE_MAX_SIZE].first_name);
    strcpy(per_son.last_name, queue[(index+head)%QUEUE_MAX_SIZE].last_name);
    strcpy(per_son.pers_nbr, queue[(index+head)%QUEUE_MAX_SIZE].pers_nbr);

    pers = &per_son;
    printf("Förnamn: %s\n", per_son.first_name);
}

编辑 2: 我自己想出来的。我不得不编辑 get_person 函数并删除 per_son 结构并将 strcpy 更改为 pers 而不是 pers_son。

【问题讨论】:

  • 在发布的代码中,first_name 永远不会被填充。你能发布填充它的代码吗?
  • ╠ 在代码页 437 中为 0xCC,MSVC fills 0xCC to uninitialized memory to help debugging。这意味着您访问了未初始化的内存。你可以在这里找到关于 ╠ 和 0xCC 的大量问题

标签: c struct printf typedef


【解决方案1】:

person dequeue_person;person per_son; 是两个不同的对象。 您将名称放在一个但打印另一个,所以它仍然是垃圾。

当您创建 person 的对象时,所有成员都未初始化,因此它是垃圾值。 当你尝试打印它时,它会在堆栈上打印垃圾值。因此你得到了这个。

编辑:问题已编辑

get_person(point_person, 9);

调用get_person()后会执行get_person()函数的代码。 因此,存在本地 per_son 对象,因此无论您输入的名称实际上是本地名称,它都会在退出 get_person() 后自动销毁 在此处打印 first_name 本身是个好主意,但仍然存在一个错误,即您在调用环境中执行 printf() 也会为您提供本地对象的 first_name(即垃圾)。

如果你想在get_person() 中传递person 并想在两个地方打印相同的名称,试试这个:

    person dequeue_person;
    person *point_person = &dequeue_person;
    get_person(point_person, 9);
    printf("%s", point_person->first_name);

void get_person(person *pers, int index)
{
    strcpy(pers->first_name, queue[(index+head)%QUEUE_MAX_SIZE].first_name);
    strcpy(pers->.last_name, queue[(index+head)%QUEUE_MAX_SIZE].last_name);
    strcpy(pers->pers_nbr, queue[(index+head)%QUEUE_MAX_SIZE].pers_nbr);

    printf("In get person First name : %s\n", pers->first_name);
}

在这种情况下,传递给get_person() 的指针指向在调用环境时创建的同一个对象。请参阅get_person() 的实现

我希望你现在明白了。

【讨论】:

  • 效果很好,但我需要将 pers 传递给 point_person,我不知道该怎么做。
  • 请看我更新的帖子,希望它能提供更多信息。
【解决方案2】:

结构的内容未初始化。您需要将它们设置为某种东西。

你可以像这样初始化你的结构:

struct person dequeue_person = { "joe", "blogs", "42" };

或者你可以创建一个空结构

struct person dequeue_person = { "", "", "" };

清除整个结构并不少见:

struct person dequeue_person;
memset( &person, 0, sizeof(struct person) );

编辑....我注意到在您的垃圾输出的最后,出现了“约翰”这个词。难道这是你队列的尽头? ie 元素QUEUE_MAX_SIZE-1。可能您没有正确初始化indexhead,或者您在错误的时间更改了它们的值。

或者,index+head 可能不是处理队列的正确方法。通常你会有一个head 和一个tail 索引,你不会以这种方式添加它们。您所做的意味着index 实际上是队列中的元素数。

【讨论】:

  • 将结构放在前面会产生很多错误,例如“不允许不完整的类型”。我在不使用 struct 的情况下尝试了它,它没有给出任何错误,但没有返回任何输出。
  • 嗯,缺少输出是因为我正在清除结构以包含空字符串...当您创建一个空变量并且不为其分配任何内容时,您到底希望它做什么包含?您的代码中一定有一些您没有向我们展示的内容。
  • 您需要显示填充queue 的代码,并准确说明headindex 的值是什么。我认为字符串没有正确终止。
  • index 为 9,head 为 0,queue[9].first_name 包含“John”,并且从函数内部打印 per_son.first_name 工作得很好,当我尝试在函数外部使用它时因为文本变得乱码。
  • 我想通了!我必须摆脱函数中的 per_son 以及将 strcpy 中的 per_son 更改为 pers。现在它返回正确的值,没有垃圾。
【解决方案3】:

您应该使用经过的人 - 而不是本地人:

void get_person(person *pers, int index)
{
    // NOT NEEDED: person per_son;

    strcpy(pers->first_name, queue[(index+head)%QUEUE_MAX_SIZE].first_name);
    strcpy(pers->last_name, queue[(index+head)%QUEUE_MAX_SIZE].last_name);
    strcpy(pers->pers_nbr, queue[(index+head)%QUEUE_MAX_SIZE].pers_nbr);

    // WRONG: pers = &per_son;
    printf("Förnamn: %s\n", pers->first_name);
}

【讨论】:

    猜你喜欢
    • 2018-02-17
    • 2013-10-30
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多