我是std
命名空间的菜鸟,我正在编写循环遍历目录中所有jpeg文件的代码并删除任何感叹号。我正在尝试使用std::string
和std::vector
。我的问题是我的变量tempname:const char tempname = (char) *filelist[j].c_str();
随着向量filelist
中的字符串的变化而变化(它不应该变化 - 它是一个常量变量。这是我的WinMain函数的主要内容:
std::vector<std::string> filelist;
if (!dirExists(directory)) //checks if a directory exists
{
CreateDirectory("resized", NULL);
}
std::vector<std::string> filelist = findFiles("*.jpg"); //finds files in its directory with a given extension
int result; //for rename function
for (unsigned int j=0; j< filelist.size(); j++)
{
std::string::size_type pos = filelist[j].find("!"); //check for exclamation points
if (std::string::npos != pos) //found one at index "pos" in the string
{
switch (MessageBox(window, (LPCSTR)filelist[j].c_str(), "Illegal filename - Rename?", MB_YESNO)) //user input
{
case IDYES:
{
const char tempname = (char) *filelist[j].c_str(); //the problem
//attempt to remove the exclamation point
result = rename(&tempname, filelist[j].erase(pos, 1).c_str());
if (result == 0)
MessageBox(window, "Renamed File", "Information", MB_OK);
else
MessageBox(window, "Error renaming file", "Error", MB_OK);
break;
}
case IDNO:
{
break;
}
}
}
}
假设文件名包含不超过一个感叹号。如果我将tempname定义为const char*
,这将是有意义的,因为它将是一个指针 - 如果它指向的数据发生了变化,tempname的值可能会在不违反const
声明的情况下发生变化。但是拿走指针,我感到很困惑。
答案 0 :(得分:3)
您意识到您的tempname声明意味着您将只复制一个字符?我很确定这不是你想要的。
您可能想要复制字符串本身并更改代码,如下所示:
std::string const tempname = filelist[j];
//attempt to remove the exclamation point
result = rename(tempname.c_str(), filelist[j].erase(pos, 1).c_str());
至于为什么你所谓的const变量如果你操纵底层字符串会改变它的值,请记住,在你的原始声明中,tempname是一个值的指针,所有你说的就是指针不会改变它的值。它没有,但是指针确实如此。
此外,当将c_str与字符串操作组合时,你几乎进入了危险区域 - 看一下c_str here的文档,它明确指出在字符串对象上调用mutating成员函数可能会使结果无效c_str()调用。将std :: string与C字符串惯用法混合时必须小心。
答案 1 :(得分:0)
您发布的代码具有未定义的行为,这意味着
什么都可能发生。您定义了一个char
,tempname
,
然后将其地址传递给rename
。 rename
要求
指向'\0'
终止字符串的指针;唯一合法的
字符串将是一个空字符串。
如果您将tempname
的定义替换为:
char const* tempname = filelist[j].c_str();
然后你有未定义的行为;打电话给
filelist[j].erase
使此指针无效。在实践中,它
事实上将继续指向filelist[j]
中的数据
(因为事实上,erase
不会重新分配,所以
tempname
将继续指向第一个字符
filelist[j]
)。
你可能想要的是:
std::string newName( filelist[j] );
newName.erase( std::remove( newName.begin(), newName.end(), '!' ),
newName.end() );
result = rename( filelist[j].c_str(), newName.c_str() );
filelist[j] = newName;