2014-12-23 37 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

相关问题