指针混淆 - c ++

时间:2011-05-25 02:23:42

标签: c++ pointers

我的任务是对C ++应用程序进行简单的更改。不幸的是,我来自Java背景,而且我遇到了一些指针问题。

有问题的代码读取给定目录中的文件列表(使用环境变量设置),并对每个文件执行某些操作。

char * rebuildDir = getenv("REBUILD_DIR");
char * currentFile;
DIR *asciiDir;
struct dirent *ent;

asciiDir = opendir(rebuildDir);
if (asciiDir != NULL)
{
    while ((ent = readdir(asciiDir)) != NULL)
    {
        std::cout << "rebuild sensor, rebuild dir is " << getenv("REBUILD_DIR") << std::endl;
        currentFile = rebuildDir;
        strcat(currentFile, ent->d_name);
        ifstream raw(currentFile);
        while(raw)
        {
            ...snip...
        }
        raw.close();
    }

    closedir(asciiDir);
}

如您所见,目的是将环境变量存储一次,然后将其复制到currentFile,然后将当前文件名连接到currentFile,准备传入ifstream。

问题在于

currentFile = rebuildDir;

没有重置为环境变量,所以strcat继续使用旧文件名并附加到它,所以:

/home/file1
/home/file2
/home/file3

将以

执行
/home/file1
/home/file1/home/file2
/home/file1/home/file2/home/file3

通过循环。我猜我用指针犯了一个错误,但我无法追踪它。

感谢您的帮助,并为这个微不足道的问题道歉。

PS - 如果有一个明显更好的方法来完成我的任务,请随时指出:)

3 个答案:

答案 0 :(得分:5)

当前文件指向与rebuilddir相同的内存,因此您可以修改字符串。你需要复制字符串。你可以这样做:

char currentFile[MAX_PATH];
snprintf(currentFile, MAX_PATH, "%s%s", rebuildDir, ent->d.name);

答案 1 :(得分:3)

“...不会重置为环境变量”。为什么它会“重置”为什么?您将指针currentFile瞄准rebuildDir指向的实际环境变量值。然后你通过strcat修改指针,即你实际上正在修改(即销毁)原始环境变量值。

你不应该这样做。如果要根据环境变量的值构建新名称,则必须将该值复制到一边,然后修改副本,而不是尝试销毁原始文件。

例如,您可以使用std::string在原始值

上创建副本
const char *rebuildDir = getenv("REBUILD_DIR");
...
std::string currentFile = rebuildDir;
currentFile += ent->d_name;
ifstream raw(currentFile.c_str());

答案 2 :(得分:1)

int main(int argc, char *argv[])
{
    char* pDir = getenv("REBUILD_DIR");

    if (! pDir)
    {
        cerr << "did not find ENV var\n";
        exit(1);
    }

    string rebuildDir(pDir);

    DIR* asciiDir;

    if ((asciiDir = opendir(rebuildDir.c_str())) != NULL)
    {
        std::cout << "rebuild sensor, rebuild dir is " << rebuildDir << std::endl;

        struct dirent *ent;

        while ((ent = readdir(asciiDir)) != NULL)
        {
            string currentFile(rebuildDir);

            currentFile += '/' + string(ent->d_name);

            //probably want to skip "." and ".." entries...

            /*
            ifstream raw(currentFile);

            while(raw)
            {
                ...snip...
            }

            raw.close();
            */
        }

        closedir(asciiDir);
    }
    else
    {
        cerr << "coult not open dir\n";
        exit(1);
    }

    return 0;
}