2014-12-23 76 views
1

假設有兩個字符串:如何用原始轉義序列解析字符串?

string parse(const string& s) { 
    // how to write this function? 
} 

int main() { 
    string s1 = R"(hello\n\"this is a string with escape sequences\"\n)"; 
    string s2 = "hello\n\"this is a string with escape sequences\"\n"; 
    assert(parse(s1) == s2); 
} 

我的問題是,如何寫功能parse()爲了使斷言成功,比一些手工製作的代碼遍歷字符串和檢查對每一個可能的轉義序列等?有沒有現成的做法呢?

+0

您需要列出解析的所有規則以方便編寫parse()函數。 – gman

+0

原始序列或否,解析算法是相同的。 – user1095108

+0

@gman規則與C++字符串文字轉義序列的規則相同 – goodbyeera

回答

-1

這可能是使用正則表達式來實現轉義序列替換的最簡單方法,但如果您堅持不做,可以將字符串作爲打印字符串的有效C++程序的一部分寫入文件到一個文件,然後從文件中讀取它。 (這也可以提高在所有無臨時文件工作)

#include <iostream> 
#include <fstream> 
#include <string> 
#include <cstdlib> 
#include <assert.h> 

using std::string; 

string parse(const string& s) { 
    std::ofstream ftmp("tmpsrc.cpp"); 
    ftmp << "#include <iostream>\nint main(int argc, char* argv[]){\n"; 
    ftmp << " std::cout << \"" << s << "\";\nreturn 0;}\n\n"; 
    ftmp.close(); 
    system("g++ -o tmpprint tmpsrc.cpp"); 
    system("./tmpprint > tmpstr.txt"); 
    std::ifstream fin("tmpstr.txt",std::ios::in|std::ios::binary); 
    fin.seekg(0,std::ios::end); 
    int size=fin.tellg(); 
    fin.seekg(0); 
    string res; 
    res.resize(size); 
    fin.read(&res[0],size); 
    fin.close(); 
    // Add delete of temp files here 
    return res; 
} 

int main() { 
    string s1 = R"(hello\n\"this is a string with escape sequences\"\n)"; 
    string s2 = "hello\n\"this is a string with escape sequences\"\n"; 
    assert(parse(s1) == s2); 
} 
+0

感謝您給出完整的程序。錯綜複雜,它確實有效。如果沒有其他更好的解決方案出現,我會以此作爲答案。再次感謝。 – goodbyeera

+0

好的。如果我使用MSVC或CLang? – borisbn

+0

你可以用它來做,只有編譯器命令細節發生變化。對於MSVC,你也可能有PATH問題。 – Photon

0

你可以使用字符串流。檢查字符串的每個字符是否有反斜槓「\」字符。找到後,檢查下一個字符是否是有效的轉義字符。然後爲該轉義字符序列在字符串流中寫入一個字符串。

std::string parse(const std::string& s) 
{ 
    std::stringstream ss{""}; 

    for(size_t i = 0; i < s.length(); i++) 
    { 
     if (s.at(i) == '\\') 
     { 
      switch(s.at(i + 1)) 
      { 
       case 'n': ss << "\n"; i++; break; 
       case '"': ss << "\""; i++; break; 
       default: ss << "\\";  break; 
      }  
     } 
     else 
     { 
      ss << s.at(i); 
     } 
    } 

    return ss.str(); 
} 
0

IMHO,C++逃脫sequencies是很容易更換他們手動

string string_replace(const string & s, const string & findS, const std::string & replaceS) 
{ 
    string result = s; 
    auto pos = s.find(findS); 
    if (pos == string::npos) { 
     return result; 
    } 
    result.replace(pos, findS.length(), replaceS); 
    return string_replace(result, findS, replaceS); 
} 

string parse(const string& s) { 
    static vector< pair< string, string > > patterns = { 
     { "\\\\" , "\\" }, 
     { "\\n", "\n" }, 
     { "\\r", "\r" }, 
     { "\\t", "\t" }, 
     { "\\\"", "\"" } 
    }; 
    string result = s; 
    for (const auto & p : patterns) { 
     result = string_replace(result, p.first, p.second); 
    } 
    return result; 
} 

int main() { 
    string s1 = R"(hello\n\"this is a string with escape sequences\"\n)"; 
    string s2 = "hello\n\"this is a string with escape sequences\"\n"; 
    cout << parse(s1) << endl; 
    cout << (parse(s1) == s2) << endl; 
} 

輸出:

你好 「這是與轉義序列的字符串」

http://ideone.com/jMAfRK

+0

支持整套轉義序列應該有點複雜:http://en.cppreference.com/w/cpp/language/escape – etham

相關問題