std::out_of_range 在设置 QLineEdit 时
std::out_of_range while setting a QLineEdit
在我的 C++ 应用程序中,我必须 select 一个带有 QFileDialog class 的文件。
然后,我验证我的文件名是否正确(必须以 "VG" 开头)。
我的文件有这样的结构:VGx-xx-xxxx-xxx-xxx.pigs
之后呢,我在关联的QLineEdit里面设置了。
但是每次我select一个好的文件,它就崩溃了,我不明白为什么。
这是我的不同功能:
打开 QFILE 对话框 WINDOW
/** 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");
}
}
文件名验证
/** 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 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;
}
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;
}
不安全,因为:
1- 您不检查 pigsNameTable
是否在索引处(如果 vector
?)或键(如果 map
?)是否有元素 0
2- 您没有检查 pigsNameTable[0]
是否有超过 2 个元素。见 erase documentation:
pos: Position of the first character to be erased. If this is greater
than the string length, it throws out_of_range.
你可以简单地做:
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;
}
}
如果pigsNameTable
是vector
,测试可以是!pigsNameTable.empty()
,如果是map
,pigsNameTable.find(0) != pigsNameTable.end()
...
在我的 C++ 应用程序中,我必须 select 一个带有 QFileDialog class 的文件。 然后,我验证我的文件名是否正确(必须以 "VG" 开头)。
我的文件有这样的结构:VGx-xx-xxxx-xxx-xxx.pigs
之后呢,我在关联的QLineEdit里面设置了。 但是每次我select一个好的文件,它就崩溃了,我不明白为什么。
这是我的不同功能:
打开 QFILE 对话框 WINDOW
/** 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");
}
}
文件名验证
/** 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 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;
}
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;
}
不安全,因为:
1- 您不检查 pigsNameTable
是否在索引处(如果 vector
?)或键(如果 map
?)是否有元素 0
2- 您没有检查 pigsNameTable[0]
是否有超过 2 个元素。见 erase documentation:
pos: Position of the first character to be erased. If this is greater than the string length, it throws out_of_range.
你可以简单地做:
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;
}
}
如果pigsNameTable
是vector
,测试可以是!pigsNameTable.empty()
,如果是map
,pigsNameTable.find(0) != pigsNameTable.end()
...