2010-12-07 324 views
0

如何在C(++)中將"A\r\nB\tC\nD"轉換爲"A\\r\\nB\\tC\\nD"將特殊字符(如 n)轉換爲其轉義版本

對於純C和純C++解決方案,理想情況下只使用標準庫和紅利upvote。

+0

什麼是保存的原始字符串?例如字符(即0x0D和0x0A)或字符序列(即\,後面跟着n)是否是`\ r` /`\ n`? – Nim 2010-12-07 14:11:20

回答

3

當然,與wchar_tstd::stringstd::wstring,如果你使用的是寬字符串替換char

std::string input(/* ... */); 
std::string output; 
for(std::string::const_iterator it = input.begin(); it != input.end(); ++it) 
{ 
    char currentValue = *it; 
    switch (currentValue) 
    { 
    case L'\t': 
     output.append("\\t"); 
     break; 
    case L'\\': 
     output.append("\\\\"); 
     break; 
    //.... etc. 
    default: 
     output.push_back(currentValue); 
    } 
} 

你可以做到這一點在C,但它的將是更困難的,因爲你不知道提前緩衝區大小(雖然你可以使原字符串的大小2倍的最壞情況下的猜測) 。即

//Disclaimer; it's been a while since I've written pure C, so this may 
//have a bug or two. 
const char * input = // ...; 
size_t inputLen = strlen(input); 
char * output = malloc(inputLen * 2); 
const char * inputPtr = input; 
char * outputPtr = output; 
do 
{ 
    char currentValue = *inputPtr; 
    switch (currentValue) 
    { 
    case L'\t': 
     *outputPtr++ = '\\'; 
     *outputPtr = 't'; 
     break; 
    case L'\\': 
     *outputPtr++ = '\\'; 
     *outputPtr = '\\'; 
     break; 
    //.... etc. 
    default: 
     *outputPtr = currentValue; 
    } 
} while (++outputPtr, *inputPtr++); 

(記住添加錯誤處理到C版本之類的malloc故障;))

+0

這就是爲什麼我希望有一些圖書館功能;但是謝謝。 – mbq 2010-12-07 14:38:03

+0

@mbq:然後只使用C++版本;我一直在使用它多年,並知道它沒有錯誤:)(地獄,如果你在C++中,那麼你**使用`std :: string`,對吧?:)) – 2010-12-07 14:41:52

+0

@ Bill當然,除非因爲與其他代碼交互而不得不混淆C,而且問題很簡單,比如strlen。 – mbq 2010-12-07 15:37:02

1

我懷疑是否有任何標準庫函數直接執行此操作。最有效的方法是簡單地遍歷輸入緩衝區字符,有條件地複製到輸出緩衝區,用一些特殊的狀態機邏輯來處理'\'等。

我確定有辦法做這與strchr()等的各種組合有關,但在一般情況下可能效率較低。

0

我將創建的32個const char*文字,一個用於每個控制碼(ASCII 0到ASCII的查找表31)。然後,我會迭代原始字符串,將非控制字符(ASCII> = 32)複製到輸出緩衝區,並將查找表中的值替換爲ASCII 0-31。

注1:ASCII 0爲C字符串明顯特殊(未所以對於C++。)

注2:該查找表將包含C轉義序列具有他們代碼(\n\r等)和反斜槓加上十六進制/八進制/十進制代碼。

0

這是C#中的一個算法。也許你可以把它當作僞代碼並將其轉換爲C++。

public static string EscapeChars(string Input) string Output =「」;

foreach (char c in Input) 
{ 
    switch (c) 
    { 
     case '\n': 
      Output += "\\n"; 
      break; 
     case '\r': 
      Output += "\\r"; 
      break; 
     case '\t': 
      Output += "\\t"; 
      break; 
     default: 
      Output += c; 
      break; 
    }     
} 
return Output; 

}

2

這裏是我想出了...

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

inline char needs_escaping(char val) { 
     switch(val) { 
       case '\n': return 'n'; 
       case '\r': return 'r'; 
       case '\t': return 't'; 
     } 
     return 0; 
} 

char *escape_string(char *in) { 
     unsigned int needed = 0, j = 0, length = strlen(in), i; 
     for(i = 0; i < length; i++) { 
       if(needs_escaping(in[i])) needed++; 
     } 

     char *out = malloc(length + needed + 1); 
     for(i = 0; i < length; i++) { 
       char escape_val = needs_escaping(in[i]); 
       if(escape_val) { 
         out[j++] = '\\'; 
         out[j++] = escape_val; 
       } 
       else { 
         out[j++] = in[i]; 
       } 
     } 
     out[length + needed] = '\0';  
     return out; 
} 

int main() { 
     char *in = "A\r\nB\tC\nD"; 
     char *out = escape_string(in); 
     printf("%s\n", out); 
     free(out); 
     return 0; 
}