2013-07-05 2 views
0

나는 std 네임 스페이스를 가진 멍청한 사람이다. 나는 디렉토리에있는 모든 jpeg 파일을 반복하고 느낌표를 제거하는 코드를 작성하고있다. std::stringstd::vector을 사용하려고합니다. 내 문제는 내 변수 tempname : 말아야 벡터 filelist 변경의 문자열로 const char tempname = (char) *filelist[j].c_str(); 변경 (- 여기 내의 WinMain 함수의 고기는 상수 변수 :자동 파일 이름 변경 - const 변수의 값이 변경되고 있습니까?

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

"const를 숯불 tempname는"한 문자입니다 :

은 당신이 아마 원하는 것은 무엇인가이다 – doctorlove

답변

3

임시 이름 선언은 당신이 exac 한 캐릭터? 나는 그것이 당신이 원하는 것이 아니라고 확신합니다.

다음과 같이 당신은 아마 문자열 자체의 복사본을 만들고 코드를 변경하려면 :

기본이되는 문자열을 조작 할 경우 가정 CONST 변수가 명심 값을 변경 이유에
  std::string const tempname = filelist[j]; 
      //attempt to remove the exclamation point 
      result = rename(tempname.c_str(), filelist[j].erase(pos, 1).c_str()); 

그 원래 선언에서 tempname은 포인터이고 값은 포인터가 값을 변경하지 않는다는 것입니다. 그것은 아니지만 pointee 않았다.

또한 c_str과 문자열 조작을 결합하면 매우 위험한 영역으로 들어가게됩니다. c_str here에 대한 설명서를 보면 문자열 객체의 mutating 멤버 함수를 호출하면 c_str의 결과가 무효화 될 수 있습니다() 호출. std :: string과 C 문자열 숙어를 혼합 할 때는주의해야합니다.

0

게시하는 코드에 정의되지 않은 동작이 있습니다. 즉, 일이 발생할 수 있습니다. char, tempname, 을 정의한 다음 해당 주소를 rename으로 전달합니다. rename은 은 종료 된 문자열 '\0'에 대한 포인터입니다. 유일한 합법적 인 하나 인 문자열은 빈 문자열입니다.

당신이 tempname의 정의를 교체하는 경우 : 나중에

char const* tempname = filelist[j].c_str(); 

당신이 정의되지 않은 행동; filelist[j].erase을 호출하면이 포인터가 무효화됩니다. 실제로, 그것은 사실의 데이터를 가리 키도록 계속 filelist[j] (사실, erase이 재 할당되지 않기 때문에, 그래서 tempnamefilelist[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;