C中的字符串解析。将字符串的一部分复制到另一个字符串

C中的字符串解析。将字符串的一部分复制到另一个字符串,c,string,text-parsing,arrays,C,String,Text Parsing,Arrays,我正在尝试编写一个函数,它可以将字符串中的所有转义序列转换为不可打印的形式。基本上,如果我有一个字符串“This\n make a new line”,我希望它是“This” 做一条新的线”。到目前为止我已经知道了。我是从main打来的: int main() { unescape("This \\n\\n is \\t\\t\\t string number \\t 7."); return 0; } char* unescape(char* s) { char *e

我正在尝试编写一个函数,它可以将字符串中的所有转义序列转换为不可打印的形式。基本上,如果我有一个字符串“This\n make a new line”,我希望它是“This” 做一条新的线”。到目前为止我已经知道了。我是从main打来的:

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

你最好用这个

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

}

你最好用这个

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

}

你最好用这个

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

}

你最好用这个

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

}

我同意Anonymouse的观点。首先替换所有
\n
,然后替换所有
\t
,既笨拙又低效。相反,只通过字符串一次,在执行时替换所有转义字符

我在下面的代码示例中遗漏了空间分配;IMHO这是一项单独的职责,不是算法的一部分,因此不属于同一功能

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
。 这种实现应该更快,尤其是在转义字符相对较少的很长字符串上。 我发布它主要是为了演示优化如何使代码更复杂、可读性更低;因此,可维护性较差,更容易出错。有关详细讨论,请参阅:


我同意Anonymouse的观点。首先替换所有
\n
,然后替换所有
\t
,既笨拙又低效。相反,只通过字符串一次,在执行时替换所有转义字符

我在下面的代码示例中遗漏了空间分配;IMHO这是一项单独的职责,不是算法的一部分,因此不属于同一功能

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
。 这种实现应该更快,尤其是在转义字符相对较少的很长字符串上。 我发布它主要是为了演示优化如何使代码更复杂、可读性更低;因此,可维护性较差,更容易出错。有关详细讨论,请参阅:


我同意Anonymouse的观点。首先替换所有
\n
,然后替换所有
\t
,既笨拙又低效。相反,只通过字符串一次,在执行时替换所有转义字符

我在下面的代码示例中遗漏了空间分配;IMHO这是一项单独的职责,不是算法的一部分,因此不属于同一功能

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
。 这种实现应该更快,尤其是在转义字符相对较少的很长字符串上。 我发布它主要是为了演示优化如何使代码更复杂、可读性更低;因此,可维护性较差,更容易出错。有关详细讨论,请参阅:


我同意Anonymouse的观点。首先替换所有
\n
,然后替换所有
\t
,既笨拙又低效。相反,只通过字符串一次,在执行时替换所有转义字符

我在下面的代码示例中遗漏了空间分配;IMHO这是一项单独的职责,不是算法的一部分,因此不属于同一功能

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
。 这种实现应该更快,尤其是在转义字符相对较少的很长字符串上。 我发布它主要是为了演示优化如何使代码更复杂、可读性更低;因此,可维护性较差,更容易出错。有关详细讨论,请参阅:


我要试试这个。不过,出于好奇,有没有办法让我的方法成功?只是想知道未来的参考,因为我已经花了这么多时间试图让它发生的方式。我的版本与strchr将更快。另外,我正在(错误地)搜索\\n-因此请删除IF语句。最后,Ruud的函数原型比提问者要好,const是你的朋友,特别是如果你尝试修改常量字符串(例如“This\\n\\n is\\t\\t\\t string number\\t 7”),我最终使用了Ruud版本的代码。我用最后的代码编辑了我的第一篇文章。遗憾的是,我在理解Anonymouse的代码时遇到了一些困难,但非常感谢你们两位。@Anonymouse:的确,
strchr
更快,但速度不是一切。请看我的编辑;还有我超链接的维基讨论。我要试试这个。不过,出于好奇,有没有办法让我的方法成功?只是想知道未来的参考,因为我已经花了这么多时间试图让它发生的方式。我的版本与strchr将更快。另外,我正在(错误地)搜索\\n-因此请删除IF语句。最后,Ruud的函数原型比提问者要好,const是你的朋友,特别是如果你尝试修改常量字符串(例如“This\\n\\n is\\t\\t\\t string number\\t 7”),我最终使用了Ruud版本的代码。我用最后的代码编辑了我的第一篇文章。遗憾的是,我在理解Anonymouse的代码时遇到了一些困难,但非常感谢你们两位。@Anonymouse:的确,
strchr
更快,但速度不是一切。请看我的编辑;还有我超链接的维基讨论。我要试试这个。不过,出于好奇,有没有办法让我的方法成功?只是想知道未来的参考,因为我已经花了这么多时间试图让它发生的方式。我的版本与strchr将更快。另外,我正在(错误地)搜索\\n-因此请删除IF语句。最后,Ruud的函数原型比提问者要好,const是你的朋友,特别是如果你尝试修改常量字符串(例如“This\\n\\n is\\t\\t\\t string number\\t 7”),我最终使用了Ruud版本的代码。我用最后的代码编辑了我的第一篇文章。