我试图编写一个函数,它将以不可打印的形式转换字符串中的所有转义序列。基本上如果我有一个字符串"这个\ n创建一个新行",我希望它是"这 新一行"。到目前为止,我已经得到了这个。我是从主要电话打来的:
int main()
{
unescape("This \\n\\n is \\t\\t\\t string number \\t 7.");
return 0;
}
char* unescape(char* s)
{
char *esc[2] = {"\\n", "\\t"};
int i;
char* uus = (char*)calloc(80, sizeof(char));
char* uus2 = (char*)calloc(80,sizeof(char));
strncpy(uus, s, strlen(s));
for(i = 0; i < 2; i++)
{
while(strstr(uus, esc[i]) != NULL) //checks if \\n can be found
{
//printf("\n\n%p\n\n", strstr(uus, esc[i]));
int c = strstr(uus, esc[i]) - uus; //gets the difference between the address of the beginning of the string and the location
//where the searchable string was found
uus2 = strncpy(uus2, uus, c); //copies the beginning of the string to a new string
//add check which esc is being used
strcat(uus2, "\n"); //adds the non-printable form of the escape sequence
printf("%s", uus2);
//should clear the string uus before writing uus2 to it
strncpy(uus, uus2, strlen(uus2)); //copies the string uus2 to uus so it can be checked again
}
}
//this should return something in the end.
}
基本上,我现在需要做的是在#34; \ n&#34;之后从字符串uus中取出部分。并将其添加到字符串uus2,以便我可以再次运行while循环。我想过使用strtok但是撞墙,因为它使用某种分隔符制作了两个单独的字符串,在我的情况下并不总是这样。
编辑:将其余字符串添加到uus2应该在strncpy之前。这是没有它的代码。
编辑vol2:这是有效的代码,我最终使用了它。基本上编辑了Ruud的版本,因为我必须使用的函数必须返回一个字符串。非常感谢。
char* unescape(char* s)
{
char *uus = (char*) calloc(80, sizeof(char));
int i = 0;
while (*s != '\0')
{
char c = *s++;
if (c == '\\' && *s != '\0')
{
c = *s++;
switch (c)
{
case 'n': c = '\n'; break;
case 't': c = '\t'; break;
}
}
uus[i] = c;
i++;
}
uus[i] = '\0';
return uus;
}
答案 0 :(得分:2)
我同意Anonymouse。首先替换所有\n
,然后替换所有\t
,这既笨拙又效率低下。而是通过字符串进行单次传递,替换所有转义字符。
我在下面的代码示例中留下了空间分配;恕我直言,这是一个单独的责任,而不是算法的一部分,因此不属于同一个功能。
void unescape(char *target, const char *source)
{
while (*source != '\0')
{
char c = *source++;
if (c == '\\' && *source != '\0')
{
c = *source++;
switch (c)
{
case 'n': c = '\n'; break;
case 't': c = '\t'; break;
}
}
*target++ = c;
}
*target = '\0';
}
修改强>
这是一个替代版本,使用Anonymouse建议的strchr
。
此实现应该更快,尤其是在具有相对较少转义字符的非常长的字符串上。
我发布它主要是为了演示优化如何使您的代码更复杂,更不易读;因此不易维护且更容易出错。有关详细讨论,请参阅:http://c2.com/cgi/wiki?OptimizeLater
void unescape(char *target, const char *source)
{
while (*source != '\0')
{
if (*source++ == '\\' && *source != '\0')
{
char c = *source++;
switch (c)
{
case 'n': c = '\n'; break;
case 't': c = '\t'; break;
}
*target++ = c;
}
else
{
const char *escape = strchr(source--, '\\');
int numberOfChars = escape != NULL ? escape - source : strlen(source);
strncpy(target, source, numberOfChars);
target += numberOfChars;
source += numberOfChars;
}
}
*target = '\0';
}
答案 1 :(得分:1)
你最好使用它......
char *p;
p = input_string;
while ((p=strchr (p, '\\')) != NULL)
{
if (p [1] == '\\')
{
switch (p [2])
{
case 'n' :
// handle \n
break;
case 't' :
// handle tab
break;
}
}
else
p++;
}