2016-01-24 1 views
1

Dans mon application C++, je dois sélectionner un fichier avec la classe QFileDialog. Ensuite, je vérifie que mon nom de fichier est correct (il doit commencer par "VG").std :: out_of_range lors de la définition d'un QLineEdit

Mon fichier a cette structure: VGX-xx-xxxx-xxx-xxx.pigs

Après quoi, je l'ai mis dans le QLineEdit associé. Mais chaque fois que je sélectionne un bon fichier, il plante, et je ne comprends pas pourquoi.

Voici mes différentes fonctions:

OUVERT LA QFile DIALOG FENÊTRE

/** OPEN FILE DIALOG WINDOW **/ 
void VGCCC::selectPIGSFile() 
{ 
    QString pigsFile = QFileDialog::getOpenFileName 
    (
     this, 
     tr("Select PIGS file"), 
     "./../VGCColorConfigurator/Inputs", 
     tr("Document files (*.pigs *.igs)"), 
     0, 
     QFileDialog::DontUseNativeDialog 
    ); 

    pigsPath = pigsFile; 
    if(verifyPIGSFileValidity(pigsPath.toStdString())) 
    { 
     m_filePathLine->setText(""); 
     m_filePathLine->setText(pigsPath); 
     m_testTextEdit->insertPlainText("File selected : "+pigsPath+"\n"); 
    } 
    else 
    { 
     m_filePathLine->setText("Please select a valid PIGS (Format VGx-xx-xxxx-xxx-xxx.pigs)"); 
     m_testTextEdit->insertPlainText("Uncorrect PIGS file.\n"); 
    } 
} 

VERIFICATION DU NOM DU FICHIER

/** VERIFY SELECTED PIG FILE **/ 
bool VGCCC::verifyPIGSFileValidity(std::string pigsPath) 
{ 
    splitPIGSName(pigsPath); 
    std::string verification = pigsNameTable[0].erase(2,2); 
    std::string headerName = "VG"; 

    if(!verification.compare(headerName)) 
    { 
     m_testTextEdit->insertPlainText("PIGS name is correct"); 
     return true; 
    } 
    else 
     return false; 
} 

SPLIT MÉTHODE

/** SPLIT PIGS NAME INTO TABLE **/ 
std::string* VGCCC::splitPIGSName(std::string pigsPath) 
{ 
    std::string pigsPathToSplit = pigsPath; 
    std::string delimiter = "-"; 
    size_t position = 0; 
    int i=0; 
    std::string token; 

    while ((position = pigsPathToSplit.find(delimiter)) != std::string::npos) 
    { 
     token = pigsPathToSplit.substr(0, position); 
     std::cout << token << std::endl; 
     pigsNameTable[i] = token; 
     i++; 
     pigsPathToSplit.erase(0, position + delimiter.length()); 
    } 
    pigsNameTable[4] = pigsPathToSplit.c_str(); 
    std::cout << pigsPathToSplit << std::endl; 
} 
+0

Comment est 'pigsNameTable' déclarée? –

+0

Etes-vous sûr qu'il se bloque lorsque vous sélectionnez un "bon" fichier? Je me sens comme il va plus plantage lorsque vous sélectionnez un "mauvais" fichier .... – jpo38

+0

@IgorTandetnik c'est ainsi que j'ai déclaré ma table dans ma classe.h: 'std :: string pigsNameTable [5];' et dans mon class.cpp je l'ai juste déclaré comme 'pigsNameTable'. – Tofuw

Répondre

3
bool VGCCC::verifyPIGSFileValidity(std::string pigsPath) 
{ 
    splitPIGSName(pigsPath); 
    std::string verification = pigsNameTable[0].erase(2,2); 
    std::string headerName = "VG"; 

    if(!verification.compare(headerName)) 
    { 
     m_testTextEdit->insertPlainText("PIGS name is correct"); 
     return true; 
    } 
    else 
     return false; 
} 

est dangereux parce que:

1- Vous ne vérifie pas si pigsNameTable a un élément à l'index (si un vector?) Ou une clé 0

(si un map?) 2- Vous ne vérifiez pas que pigsNameTable[0] a plus de 2 éléments. Voir erase documentation:

pos: Position du premier caractère à effacer. Si cette valeur est supérieure à la longueur de la chaîne, elle renvoie out_of_range.

Vous pouvez simplement faire:

bool VGCCC::verifyPIGSFileValidity(std::string pigsPath) 
{ 
    splitPIGSName(pigsPath); 

    if (/* test is pigsNameTable[0] exists depending on pigsNameTable's type */) 
    { 
     return pigsNameTable[0].find("VG") == 0; // return true if pigsNameTable[0] starts with "VG" 
    } 
    else 
    { 
     return false; 
    } 
} 

Si pigsNameTable est un vector le test peut être !pigsNameTable.empty(), si c'est un map, pigsNameTable.find(0) != pigsNameTable.end() ....

+0

Merci ça marche! Juste pour notifier que lorsque la condition avec "find()" renvoie 1 c'est vrai, et quand il renvoie 4294967295 c'est faux. (D'abord, je ne fais que: if (pigsNameTable [0] .find ("VG")) {faire quelque chose}, et c'était comme si ma condition était toujours valide, donc je dois préciser pigsNameTable [0] .find ("VG ") == 1! Maintenant ça marche ^^) – Tofuw

+1

' find' renvoie la position du motif dans la chaîne. Si elle renvoie 1, cela signifie que la chaîne a un caractère supplémentaire avant "VG". Si la chaîne commence par "VG", 'find' renverra' 0'. – jpo38

+0

Donc, pour compléter ma condition, je peux faire '(pigsNameTable [0] .find (" VG ") == 1 || pigsNameTable [0] .find (" VG ") == 0)' ? – Tofuw