从struct指针内部打印字符串时输出错误(VC ++ 2010)

时间:2015-08-07 12:54:44

标签: c++ visual-c++ struct printf

我发现printf(和printf_s)以及std :: cout都有一个非常奇怪的问题。我不确定这些功能是否有“故障”或错误,或者我做错了什么。由于两个函数都是一样的,我假设我没有采用正确的方法。

我的程序中有以下结构(顺便说一句,这是一个Visual C ++ 2010项目):

#pragma pack(push, 1)
typedef struct nameentry
{
    char NAME[17];
    char EXT[4];
}NAMEENTRY;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct fileentry
{
    unsigned int ID;
    NAMEENTRY FILENAME;
    unsigned int GPFID;
    unsigned long long int FPOINTER;
    size_t FILESIZE;
}FILEENTRY;
#pragma pack(pop)

现在我有以下部分代码:

NAMEENTRY fname = MCreateNameEntry("LONGFILE.JPG");
FILEENTRY* myfile_ = SearchFileByPkgID(0, fname);
printf("%s", myfile_->FILENAME.NAME);

那么这段代码应该做的是,使用NAME = LONGFILE和EXT = JPG创建一个NAMEENTRY实例。两个字符数组都以空值终止(最后一个字节为0)。然后用我正在开发的数据库中的相应数据创建一个FILEENTRY实例,然后从FILEENTRY的NAMEENTRY结构中打印文件名。

运行代码后,我得到的不是文件名,而是垃圾。尝试从错误指针打印文本时获得的经典垃圾。如果我尝试打印任何其他字段,我也会得到错误的值。

很明显,我的第一个想法是我的一个功能没有返回正确的值。所以我开始检查代码,令他惊讶的是,他们实际上返回了正确的值,结构中充满了正确的数据。我在每个字段中得到正确的值,每个字符数组都以0等结尾。

然后我说......“如果我将整个块复制到另一个FILEENTRY实例中怎么办?”,我试过这个:

NAMEENTRY fname = MCreateNameEntry("LONGFILE.JPG");
FILEENTRY* myfile_ = SearchFileByPkgID(0, fname);
FILEENTRY dMem;

memcpy(&dMem, myfile_, sizeof(FILEENTRY));

printf("%s", dMem.FILENAME.NAME);

猜猜是什么?它工作得很好。我得到了文件的名称,没有垃圾。所以我假设,问题是在printf内部(我也尝试过std :: cout,结果相同),或者在使用这些函数时我做错了。

1 个答案:

答案 0 :(得分:0)

嗯,这有帮助。似乎问题是试图返回指向局部变量的指针,正如Igor Tandetnik建议的那样。

作为一种解决方法,我不确定这是否是一种正确的处理方式,而不是定义一个局部变量,我使用calloc为FILEENTRY指针分配内存块,然后填写并返回。是的,它似乎以这种方式工作。

这是函数的实际代码:

FILEENTRY* SearchFileByPkgID(int ID, NAMEENTRY fname)
{
    FILEENTRY* myFile = (FILEENTRY*)calloc(sizeof(FILEENTRY),1);
    std::vector<int> results;
    unsigned int* dptable = GetDPTableByPkgId(ID);
    bool found = false;

    for(int x = 0; x < 1024; x++)
    {
        if(dptable[x] > 0)
        {
            fseek(PDBFILE, dptable[x], SEEK_SET);
            fread(myFile, sizeof(FILEENTRY), 1, PDBFILE);
            if(strcmp(myFile->FILENAME.EXT, fname.EXT) == 0)
                if(myFile->FILENAME.NAME[0] == fname.NAME[0])
                    results.push_back(dptable[x]);
        }
    }


    for(int y = 0; y < results.size(); y++)
    {
        fseek(PDBFILE, results[y], SEEK_SET);
        fread(myFile, sizeof(FILEENTRY), 1, PDBFILE);
        if(strcmp(myFile->FILENAME.NAME, fname.NAME) == 0)
        {
            found = true;
            break;
        }
    }

    results.clear();

    if(found)
        return myFile;
    else
        return 0L;
}

任何更多的建议都很好。