2016-02-11 82 views
2

我正在使用解析器。我想通過char解析文本文件char。qstring到qchar特殊字符

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)。

e.g:如果我通過fieldTerminator = "\n"到函數,ft = '\'(92)

有沒有一種簡單的方法將其存檔?謝謝。

+1

我不知道你問什麼,當我通過在'的QString(「\ n 「)'我得到'lt = 10'\ n''。 – Thomas

+0

-__-有趣: [屏幕](http://s16.postimg.org/59bln2k6d/Unbenannt.jpg) 爲什麼它不適合我? – immerhart

+0

因爲我誤解了這個問題,請看我的答案。 – Thomas

回答

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; 
} 
+0

看起來不錯。謝謝,明天我會檢查一下! – immerhart

+0

我認爲它不起作用,因爲'inStream >> c;'只給你一個字符,例如'\ n' – immerhart

+0

它可以工作,因爲它可以記住'rev'中的前一個字符。我在賦值'prev = c'中修正了一個錯字。所以在第二次迭代期間,prev將會是'''',而c將會是'n'。 – Thomas

0

你期待的QString FIELDTERMINATOR = 「\ n」 爲1個字符,並且包含 '行尾'?它不會這樣工作:fieldTerminator會是兩個字符長:'\'和'n';如果你想遵循printf()邏輯,你應該自己實現它(或者使用一些其他的字符串解析函數)

另外,如果我正確理解了解析器的邏輯,我會建議使用QChar作爲參數fieldTerminator,lineTerminator ,encloseChar - 這些預計是一個字符,而不是字符串,amirite?

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; 
} 

這是我使用的是什麼,現在...但我希望看到一個更好的實現

+0

什麼是'\ e'? – Thomas