我的程序在调试器中运行良好,但在发行版中却没有

时间:2019-01-20 16:48:27

标签: c

问题是,我确实在尝试寻找答案,但是没有人遇到我的问题。我有一个找到物品的功能

const char *FindItem(int id) {
    FILE *f1;
    f1 = fopen("Items.txt", "r");
    int i = 0;
    char s1[256];
    while (1) {
        fscanf(f1, "%i", &i);
        if (i == id) {
            fgetc(f1);
            fgets(s1, 256, f1);
            fclose(f1);
            return s1;
        }
        fgets(s1, 256, f1);
    }
}

main中我写了

int main() {
    printf("%s", FindItem(2));
}

在调试器中,它显示了应显示的内容,但在发行版中,它显示了2个相同的随机字符r?。谁能告诉我这是什么问题?

2 个答案:

答案 0 :(得分:1)

const char * FindItem(int id)

返回指向char的指针。

  return s1; 

从函数返回调用者s1的第一个元素的地址。

此外,函数FindItem()返回s1的那一刻消失了,因为它仅存在于函数的本地堆栈中,并且仅存在FindItem()的生存时间。

所以

  printf("%s", FindItem( ...

尝试打印返回的FindItem()所指向的数据,尽管该数据已消失,因为该函数已经返回。

要解决此问题,请定义要在调用方读取的缓冲区,并将其第一个元素的地址传递给函数:

char * FindItem(char * s1, int id)
{
    FILE *f1;
    f1 = fopen("Items.txt", "r");
    int i = 0;

    while(1)
    {
      ...


int main(void)
{
  char s1[256];
  printf("%s", FindItem(s1, 2));
}

答案 1 :(得分:1)

您的代码中存在多个问题:

  • 您不会测试fopen()是否成功打开文件。如果Items.txt无法打开,则行为不确定。
  • 您返回一个指向本地数组s1的指针。如您所见,在函数返回后访问该对象具有未定义的行为。未定义的行为可能是实际的预期行为,也可能是其他任何事情……它可能会根据执行环境(调试还是生产)而改变,或者无缘无故。
  • 您不测试fscanf()的返回值:如果在文件中找不到该数字,则循环将永远继续。

这是更正的版本:

#include <stdio.h>

char *FindItem(char *dest, int id) {
    FILE *f1;
    int i, c;

    f1 = fopen("Items.txt", "r");
    if (f1 == NULL)
        return NULL;

    while (fscanf(f1, "%i", &i) == 1) {
        if (i == id) {
            if ((c = fgetc(f1)) == EOF || c == '\n' || fgets(dest, 256, f1) == NULL) {
                *dest = '\0';
            }
            fclose(f1);
            return dest;
        }
        if (fgets(dest, 256, f1) == NULL)
            break;
    }
    fclose(f1);
    return NULL;  /* not found */
}

int main(void) {
    char s1[256];
    if (FindItem(s1, 2)) {
        printf("%s", s1);
        return 0;
    } else {
        printf("not found\n");
        return 1;
    }
}