我正在研究解析器。我想用char解析一个文本文件char。
bool parse(QString fileName,
QString fieldTerminator,
QString lineTerminator,
QString encloseChar)
{
QChar ft = *(fieldTerminator.unicode());
QChar lt = *(lineTerminator.unicode());
QChar ec = *(encloseChar.unicode());
QFile file(fileName);
if(!file.open(QIODevice::ReadOnly))
{
qDebug() << file.errorString();
return false;
}
QTextStream inStream(&file);
while(!inStream.atEnd())
{
QChar c;
inStream >> c;
if(c == ft)
qDebug() << "fieldterm";
else if(c == lt)
qDebug() << "lineterm";
else if(c == ec)
qDebug() << "encloseChar";
}
return true;
}
我在将fieldTerminator
等转换为特殊字符(QChar::SpecialCharacter
)时遇到问题。
例如:如果我将fieldTerminator = "\n"
传递给函数ft = '\'
(92)
有一种简单的方法可以存档吗?感谢。
答案 0 :(得分:1)
快速解析文本会成为一个有状态的事情。如果要将两个字符序列\
n
识别为换行符\n
,则仅比较单个字符(c == ft
)是不够的。您可以记住上一个字符并检查当前和之前的字符。
QString parse(QString const& text)
{
static QChar BACKSLASH('\\');
static QByteArray const SPECIAL_CHARS ("\"'?abfnrtv");
static QString const SPECIAL_QCHARS ("\\\"\'\?\a\b\f\n\r\t\v") ;
QString result;
QChar prev;
for( int i = 0; i < text.size(); ++i)
{
QChar c = text[i];
if( prev == BACKSLASH )
{
int idx = SPECIAL_CHARS.indexOf( c );
if( idx != -1)
{
result.append( SPECIAL_QCHARS[idx] );
}
else
{
result.append( prev );
result.append( c );
}
prev = 0;
}
else
{
result.append( c );
prev = c;
}
}
return result;
}
答案 1 :(得分:0)
您是否期望QString fieldTerminator =“\ n”为1个字符长且包含“行尾”?它不起作用:fieldTerminator将是两个字符长:'\'和'n';如果你想遵循printf()逻辑你应该自己实现(或使用一些其他的字符串解析函数)
此外,如果我正确理解你的解析器的逻辑,我建议使用QChar参数fieldTerminator,lineTerminator,encloseChar - 这些应该是一个字符,而不是字符串,amirite?
答案 2 :(得分:0)
QChar strToChar(QString str)
{
QChar ret;
if(!str.isEmpty())
{
if(str.size() == 1)
ret = str.at(0);
else if(str.size() == 2 && str.startsWith('\\'))
{
// special char
QChar tmp = str.at(1);
if(tmp == '\'')
ret = '\'';
else if(tmp == '\"')
ret = '\"';
else if(tmp == '?')
ret = '\?';
else if(tmp == '\\')
ret = '\\';
else if(tmp == 'a')
ret = '\a';
else if(tmp == 'b')
ret = '\b';
else if(tmp == 'e')
ret = '\e';
else if(tmp == 'f')
ret = '\f';
else if(tmp == 'n')
ret = '\n';
else if(tmp == 'r')
ret = '\r';
else if(tmp == 't')
ret = '\t';
else if(tmp == 'v')
ret = '\v';
}
// hex, oct, unicode missing
}
return ret;
}
这就是我现在正在使用的...但我希望看到更好的实施