我的任务是对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 - 如果有一个明显更好的方法来完成我的任务,请随时指出:)
答案 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;
}