简体   繁体   English

指针混淆 - c++

[英]Pointer confusion - c++

I've been tasked with making a simple change to a C++ application.我的任务是对 C++ 应用程序进行简单的更改。 Unfortunately I come from a Java background, and I've hit a wall with some pointer problems.不幸的是,我来自 Java 背景,并且遇到了一些指针问题。

The code in question reads in a list of files from a given directory (set using an environment variable), and does something on each file.有问题的代码从给定目录读取文件列表(使用环境变量设置),并对每个文件执行一些操作。

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);
}

As you can see, the intention is to store the environment variable once, then copy it to currentFile, then concatonate the current filename to currentFile, ready to pass into ifstream.可以看到,目的是将环境变量存储一次,然后将其复制到currentFile,然后将当前文件名连接到currentFile,准备传入ifstream。

The problem is that问题是

currentFile = rebuildDir;

does not reset to the environment variable, so strcat keeps on using the old filename and appending to it, so:不会重置为环境变量,因此 strcat 继续使用旧文件名并附加到它,所以:

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

will execute as将执行为

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

through the loop.通过循环。 I'm guessing I'm making an elementry mistake with my pointers, but I haven't been able to track it down.我猜我的指针犯了一个基本错误,但我无法追踪它。

Thanks for any help, and apologies for the trivial question.感谢您的帮助,并为这个琐碎的问题道歉。

PS - if there's a obviously better approach to accomplish my task, please feel free to point it out:) PS - 如果有明显更好的方法来完成我的任务,请随时指出:)

Current file points to the same memory as rebuilddir so you modify the string in place.当前文件指向与rebuilddir 相同的memory,因此您可以就地修改字符串。 You need to duplicate the string.您需要复制字符串。 You could do something like:您可以执行以下操作:

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

"... does not reset to the environment variable". “...不会重置为环境变量”。 Why would it "reset" to anything?为什么它会“重置”到任何东西? You are aiming your pointer currentFile to the actual environment variable value pointed by rebuildDir .您将指针currentFile指向rebuildDir指向的实际环境变量值。 And then you are modifying the pointee by strcat , ie you are essentially modifying (ie destroying) your original environment variable value.然后您通过strcat修改指针,即您实质上是在修改(即破坏)您的原始环境变量值。

You shouldn't do that.你不应该那样做。 If you want to build the new name from the value of the environment variable, you have to copy that value aside and then modify the copy, instead of trying to destroy the original.如果要从环境变量的值构建新名称,则必须将该值复制到一边,然后修改副本,而不是试图破坏原始值。

For example, you can use std::string to create the copy on the original value例如,您可以使用std::string在原始值上创建副本

const char *rebuildDir = getenv("REBUILD_DIR");
...
std::string currentFile = rebuildDir;
currentFile += ent->d_name;
ifstream raw(currentFile.c_str());
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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM