2013-10-10 1 views
1

"Sound Juicer"라는 프로그램으로 모든 CD를 컴퓨터에 복사했습니다. 그것은 잘 작동, 그것은 각 아티스트에 대한 폴더를 만들고 각 앨범 다른 폴더에 대해. 물론 mp3 파일에도 이러한 폴더가 있습니다.C++ Qt로 파일 이름 바꾸기 SIGSEGV가 발생합니다

문제는 트랙 번호, 아티스트 및 트랙 제목이 내 노래의 이름으로 표시되기를 바랍니다. Juicer가하는 일은 "Disk 1 Title"을 나타내는 파일 앞에 d1t를 추가하는 것입니다.

저는 프로그래머이기 때문에이 문제를 조금 연습하는 데 사용합니다. 이 작품 :

void MainWindow::rename(const QString & text) 
{ 
    static int _files = 0; 

    QDir dir(text); 
    QFileInfoList a = dir.entryInfoList(QDir::Files | QDir::Dirs); 
    for(int i = 2; i < a.size(); i++) 
    { 
     static QDir tmp; 

     if(a.at(i).isDir()) 
      rename(a.at(i).absoluteFilePath()); 

     if(a.at(i).fileName().startsWith("d1t") || a.at(i).fileName().startsWith("d2t")) 
     { 
      QString newFile = a.at(i).fileName().remove(0,3); 
      tmp = a.at(i).dir(); 

      if(!tmp.rename(a.at(i).fileName(), newFile)) 
       qDebug() << "Failed"; 

      _files++; 
     } 
    } 
} 

그것은, 디렉토리를 확인하는 첫 번째 파일이나 디렉토리를 선택하고 그것이 무엇인지 확인합니다. 디렉토리 인 경우 자체 (재귀)를 호출하고 일부 파일을 찾거나 디렉토리가 더 이상 존재하지 않을 때까지 다시 시작합니다. 파일이 발견되면 이름을 바꾸고 파일 카운터에 1을 더합니다.

그러나 첫 번째 2 개 또는 3 개의 디렉토리에있는 모든 파일의 이름이 변경되었습니다. 그 후 SIGSEGV가 발생했습니다. 아무도 틀린 것을 아는가? 내 디렉토리의

예 :

1 디렉토리 ("합계 41") -> 1 개 하위 디렉토리 ("모든 살인자 필러") -> 파일 "d1t01 합계 41 - Destruction.mp3 소개. "등 ... 이 하위 디렉토리 ("어쩌구 ") -> 파일 ...

2 디렉토리 ("샤인 다운 ") -> 1 개 하위 디렉토리 ("광기의 소리 ") -> 파일 d1t01. Shinedown - Devour.mp3 등 ...

3 디렉토리 ("Guns N 'Roses") -> 서브 디렉토리 ("Blah Blah") -> files ... 서브 디렉토리 ("Blah") -> files ..

+0

디버거에서 충돌이 발생한 곳을보기 위해 실행하자. –

+0

@FrankOsterfeld 여기에서 충돌 : QFileInfoList a = dir.entryInfoList (QDir :: Files | QDir :: Dirs); 나는 목록을 더 오래 살게하려고 노력한다. 그것이 범위를 벗어나면 파괴된다. 맞지? – Davlog

+0

정적을 제거하고 어떤 결과가 나타나는지보십시오. – fonZ

답변

-1

저는 fonZ와 Frank Osterfeld의 도움으로 어떻게 든 고쳐졌습니다. 마지막으로 단 하나의 경로를 선택하는 GUI를 만들었습니다. 그러나, 나는 그것을했다. 이 코드 조각은 무한 루프 또는 오버 플로우 (지금까지)를 일으키지 않고 모든 디렉토리를 찾습니다. 문제는 QDir 및 QFileInfo의 함수를 사용하여 경로를 가져 오는 것입니다. 나는 그걸로 잠시 놀았고이게 나왔다.

void MainWindow::rename(const QString& path) 
{ 
    //If invalid path return 
    if(path.isEmpty() || (!QDir(path).exists())) 
     return; 

    //entryInfoList(QDir::NoDotAndDotDot) doesn't work. 
    QFileInfoList fileList = QDir(path).entryInfoList(); 

    foreach (QFileInfo entry, fileList) { 

     //Eliminating wrong paths 
     if(entry.isDir()){ 
      if(entry.filePath().endsWith(".")) 
       continue; 

      //Start function again with new directory 
      rename(entry.filePath()); 
     } 
     else{ 

      QString fileName = entry.fileName(); 
      if(fileName.startsWith("d1t") || fileName.startsWith("d2t")){ 
       //Remove those characters 
       fileName.remove(0, 3); 

       //If renaming is successful, increment the successful files 
       //If not, increment the failed files and print an error 
       if(entry.dir().rename(entry.fileName(), fileName)) 
        files++; 
       else{ 
        addError("Could not rename " + entry.fileName() + " to " + fileName); 
        filesFailed++; 
       } 

      } 
     } 

    } 
} 
0

정적 인 경우 컴파일러에게 전체 프로그램에서 하나의 인스턴스 만 필요하지만 for 루프에 넣으려고합니다. 그건 정말 깨끗하지 않습니다. 이 상황에서 정적은 쓸모가 없다. 정적 또한 정적 초기화 혼란 문제로 인해 문제를 일으킬 수 있습니다. 그래서 정적 초기화가 정말로 필요 없다면, 그것을 삭제하고 그것을 로컬 또는 클래스 변수로 만드십시오.

당신의 방법을 재 작성하면, 그것을 더 잘 읽을 수 있기 때문에, 나는 당신이 재귀 적으로이 방법을 호출하고 그것이 무한 루프를 일으킬 수 있음을 알았다.

또 다른 문제는 파일 변수입니다. 그 목적은 무엇입니까?

void MainWindow::rename(const QString & text) { 
    int files = 0; 

    QDir dir(text); // does QDir also accept wrong paths? 
    QFileInfoList list = dir.entryInfoList(QDir::Files|QDir::Dirs); // does it return a list in all cases? 
    foreach (QFileInfo entry, list) { 
     if (entry.isDir()) { 
      //is everything always ok when doing this? 
      // POTENTIAL infinite loop 
      rename(entry.absoluteFilePath()); 
     } 
     else { 
      QString fileName = entry.fileName(); 
      if(fileName.startsWith("d1t") || fileName.startsWith("d2t")) { 
       if (!entry.dir().rename(fileName, fileName.remove(0,3))) qDebug() << "Failed"; 
       files++; 
      } 
     } 
    } 
} 
+0

파일은 이름이 변경된 파일 수를 계산합니다. – Davlog

+0

@Davlog 네,하지만 어디에서 사용합니까? 같은 클래스에서 사용한다면 클래스 변수로 선언하십시오. – fonZ

+0

괜찮 았습니다. 또한 (QDir :: Files | QDir :: Dirs)는 필요하지 않습니다. 나는 그것을 다시 제거했다. 같은 결과 – Davlog