问题描述
|
我的任务是对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-如果有明显更好的方法来完成我的任务,请随时指出:)
解决方法
当前文件指向与rebuilddir相同的内存,因此您就地修改了字符串。您需要复制字符串。您可以执行以下操作:
char currentFile[MAX_PATH];
snprintf(currentFile,MAX_PATH,\"%s%s\",rebuildDir,ent->d.name);
,\“ ...未重置为环境变量\”。为什么会“重置”为任何内容?您将指针currentFile
指向rebuildDir
指向的实际环境变量值。然后您要以ѭ7来修改pointe,也就是说,您实质上是在修改(即销毁)原始环境变量值。
你不应该那样做。如果要从环境变量的值构建新名称,则必须将其复制到一边,然后修改副本,而不是尝试破坏原始值。
例如,您可以使用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;
}