2013-01-03 2 views
1

여기서 내가 뭘 잘못 했습니까?경로에서 파일 이름을 반환하십시오.

전화

printf(filename(exename)); 

내 기능은 파일 이름

const char* filename(const string& str) 
{ 
    const char* path; 
    size_t found; 
    found=str.find_last_of("/\\"); 
    path = (str.substr(found+1)).c_str(); 

    cout << str.substr(found+1); // ------------> is name ok 

    printf("\n\n"); 
    printf(path); // ------------> is name not ok random numbers 
    printf("\n\n"); 
    return path; // ------------> is not ok random numbers 
} 
+0

, 그러나 가능 fputs 또는 풋, 또는'의 printf ("% s '에, EXENAME)'. –

+0

@WilliamPursell 그 이유를 다시 상기시켜 주시겠습니까? –

+0

파일 이름에 포맷팅 문자가 포함되어 있으면 잘못된 결과가 발생합니다. 이것은 아마도 귀하의 경우에는 문제가되지 않지만 필요하지 않을 때 문자열을 구문 분석하는 것은 낭비입니다. –

답변

2

str.substr(found+1)임시std::string을 반환합니다. 해당 에 메서드를 호출하고std::string, path에 반환 된 포인터를 할당합니다. 임시가 파괴되면 (;) 경로가 가비지를 가리 킵니다.

은 자신에게 호의를 확인하고 사용 C++ (대신 원시 잠재적으로 매달려 char* 포인터) 문자열을 저장하기 위해 std::string 같은 강력한 캐릭터 클래스를 사용하여, (C C++와 혼합되지 않음) :

std::string FileName(const std::string& str) 
{ 
    size_t found = str.find_last_of("/\\"); 
    std::string path = str.substr(found+1); // check that is OK 
    return path; 
} 

참고도 path 변수 이름을 사용하면 혼동을 일으킬 수 있습니다. 함수가 경로가 아닌 파일 이름을 반환하는 것 같습니다.

합니다 (path 변수없이) 더 간단한 재 작성 :

std::string ExtractFileName(const std::string& fullPath) 
{ 
    const size_t lastSlashIndex = fullPath.find_last_of("/\\"); 
    return fullPath.substr(lastSlashIndex + 1); 
} 


printf("Filename = %s\n", ExtractFileName("c:\\some\\dir\\hello.exe").c_str()); 

... 아니면 그냥 같은 원시 C 문자열 포인터를 얻을 std::string 잘 재생 및 c_str() 메서드 호출을 필요로하지 않습니다 cout를 (사용 C에서 printf() 기능) :

std::cout << ExtractFileName("c:\\some\\dir\\hello.exe"); 
당신은 printf와 여기에 사용해서는 안
5

당신은 임시 (str.substr(found+1)).c_str()에 의해 유지되는 메모리에 대한 포인터를 반환하는 반환해야합니다. 임시가 범위를 벗어나면 언제든지 메모리를 덮어 쓸 수 있습니다.

str.substr(found+1)string을 반환하는 표현식입니다. 이 객체는 임시 값이며이를 포함하는 표현식의 실행이 끝날 때 사라집니다. .c_str()을 사용하면이 객체가 제어하는 ​​메모리에 대한 포인터를 얻게됩니다. 객체의 수명이 지나면이 포인터는 더 이상 유효하지 않습니다.

pathstring으로 선언하고 함수가 포인터 대신 string을 반환하도록하십시오.

std::string 클래스로 작업 할 때는 일반적으로 char *의 원시 코드로 작업하지 않아야합니다. 즉, printf도 사용하지 않아야합니다. 대신 std::iostream 클래스를 사용하십시오.

+0

더 자세히 설명해 주시겠습니까? 정확히 언제 범위를 벗어날 것인가? – Rotem

+1

그러나'filename' 함수 내부의 print는'substr'가 슬래시를 찾지 않는 한 여전히 안정적인 출력을 만들어야합니다. –

+0

@WilliamPursell이 함수는 정의되지 않은 동작입니다. 'str.substr (found + 1)'표현식은 임시 표현식을 반환하는데,이 표현식은 전체 표현식의 끝에서 소멸됩니다. –

관련 문제