C 转换新行字符

C 转换新行字符,c,C,我正在尝试将新行字符\n转换为dos样式,\r\n而不使用libc 这是我的尝试,我做错了什么 for(i = 0; str[i]!='\0'; ++i) { if ('\r' == str[i] && '\n'==str[i+1]) ++count; } strPtr = malloc(i + 1 + count); for(i = j = 0; str[i]!='\0'; ++i) { if ('\r' == str[i])

我正在尝试将新行字符\n转换为dos样式,\r\n而不使用libc

这是我的尝试,我做错了什么

       for(i = 0; str[i]!='\0'; ++i)
{
   if ('\r' == str[i] && '\n'==str[i+1]) 
       ++count;
}

strPtr = malloc(i + 1 + count);

for(i = j = 0; str[i]!='\0'; ++i)
{
   if ('\r' == str[i]) 
   strPtr[j++] = "";
}

strPtr[j] = 0;
输出现在应该是
“嗨\r\n,你好吗\r\n,你还好吗\r\n”

这里有很多问题。首先,使用原始缓冲区就地修改字符串。但是,原始缓冲区没有足够的空间来存储额外的
\r
字符。您需要分配一个更大的缓冲区

其次,UNIX样式的回车字符不存储为两个独立的
\
n
字符。它是一个ASCII字符,值为
0xA
,可以使用转义序列
\n
表示。因此,要检查当前字符是否为换行符,您需要说
strprtr[i]='\n'

最后,当您说
strprtr[i-1]='\r'
时,您正在覆盖旧的缓冲区。这将替换
\n
前面的字符(例如
Hi
中的
i

基本上,您要做的是为输出创建第二个缓冲区,并将字符串逐字符复制到输出缓冲区。当遇到
\n
字符时,不是将单个
\n
复制到新缓冲区,而是复制
\r\n


输出缓冲区的大小需要是输入缓冲区大小的两倍,以处理输入字符串的情况,其中每个字符都是
\n
,加1表示空终止符。但是,您可以通过预先计算原始字符串中的
\n
字符数来计算输出缓冲区的最佳大小。

这里有很多问题。首先,使用原始缓冲区就地修改字符串。但是,原始缓冲区没有足够的空间来存储额外的
\r
字符。您需要分配一个更大的缓冲区

其次,UNIX样式的回车字符不存储为两个独立的
\
n
字符。它是一个ASCII字符,值为
0xA
,可以使用转义序列
\n
表示。因此,要检查当前字符是否为换行符,您需要说
strprtr[i]='\n'

最后,当您说
strprtr[i-1]='\r'
时,您正在覆盖旧的缓冲区。这将替换
\n
前面的字符(例如
Hi
中的
i

基本上,您要做的是为输出创建第二个缓冲区,并将字符串逐字符复制到输出缓冲区。当遇到
\n
字符时,不是将单个
\n
复制到新缓冲区,而是复制
\r\n


输出缓冲区的大小需要是输入缓冲区大小的两倍,以处理输入字符串的情况,其中每个字符都是
\n
,加1表示空终止符。但是,您可以通过预先计算原始字符串中的
\n
字符数来计算输出缓冲区的最佳大小。

您不能在适当的位置执行此操作。您正在为每个'\n'添加一个新字符('\r'),这意味着字符串必须展开。最坏的情况是每个字符都是'\n',这意味着我们将使字符串的大小加倍。因此,让我们创建一个两倍于原始字符串大小的缓冲区

strtmp = malloc(strlen(str) * 2 + 1); /* +1 for null */
strcpy(strtmp, str);
strptr = strtmp;

for (i = 0; str[i] != 0; i++)
{
    if ((str[i] == '\\') && (str[i+1] == 'n'))
    {
        *strptr++ = '\\';
        *strptr++ = 'r';
    }

    *strptr++ = str[i];
}

printf(strtmp);
free(strtmp);

你不能在适当的地方这样做。您正在为每个'\n'添加一个新字符('\r'),这意味着字符串必须展开。最坏的情况是每个字符都是'\n',这意味着我们将使字符串的大小加倍。因此,让我们创建一个两倍于原始字符串大小的缓冲区

strtmp = malloc(strlen(str) * 2 + 1); /* +1 for null */
strcpy(strtmp, str);
strptr = strtmp;

for (i = 0; str[i] != 0; i++)
{
    if ((str[i] == '\\') && (str[i+1] == 'n'))
    {
        *strptr++ = '\\';
        *strptr++ = 'r';
    }

    *strptr++ = str[i];
}

printf(strtmp);
free(strtmp);

字符串中的
\n
是一个转义序列,由一个字符表示

您的代码应该如下所示:

int main(void)
{
    char str[] = "Hi\n, How are you \n, are you okay\n";
    char *strPtr = str;

    int i, j;
    int count=0;

    for(i = 0; str[i]!='\0'; ++i)
    {
       if (`\n` == str[i]) ++count;
    }
    strPtr = malloc(i + 1 + count);
    for(i = j = 0; str[i]!='\0'; ++i)
    {
       if ('\n' == str[i]) strPtr[j++] = `\r`;
       strPtr[j++] = str[i];
    }
    strPtr[j] = 0;

    printf("This many times we changed it", count);
}
编辑

由于您已决定更改问题(顺便说一句-只需添加问题以进行澄清,而不删除原始OP中的大块内容,因为这些答案对未来的访问者没有任何意义)-以下是代码:

int main(void)
{
    char str[] = "Hi\r\n, How are you \r\n, are you okay\r\n";

    int i, j;
    for (i = j = 0; 0 != str[i]; ++i)
    {
       if ('\r' == str[i] && '\n' == str[i + 1])
       {
          ++count;
       }
       else
       {
          str[j++] = str[i];
       }
    }
    str[j] = 0;

    .. etc - str is without \r\n but \n, count is the number of lines.

字符串中的
\n
是一个转义序列,由一个字符表示

您的代码应该如下所示:

int main(void)
{
    char str[] = "Hi\n, How are you \n, are you okay\n";
    char *strPtr = str;

    int i, j;
    int count=0;

    for(i = 0; str[i]!='\0'; ++i)
    {
       if (`\n` == str[i]) ++count;
    }
    strPtr = malloc(i + 1 + count);
    for(i = j = 0; str[i]!='\0'; ++i)
    {
       if ('\n' == str[i]) strPtr[j++] = `\r`;
       strPtr[j++] = str[i];
    }
    strPtr[j] = 0;

    printf("This many times we changed it", count);
}
编辑

由于您已决定更改问题(顺便说一句-只需添加问题以进行澄清,而不删除原始OP中的大块内容,因为这些答案对未来的访问者没有任何意义)-以下是代码:

int main(void)
{
    char str[] = "Hi\r\n, How are you \r\n, are you okay\r\n";

    int i, j;
    for (i = j = 0; 0 != str[i]; ++i)
    {
       if ('\r' == str[i] && '\n' == str[i + 1])
       {
          ++count;
       }
       else
       {
          str[j++] = str[i];
       }
    }
    str[j] = 0;

    .. etc - str is without \r\n but \n, count is the number of lines.

<>所有C语言中的转义序列字符都是一个字符,只存储在一个字节的内存中,不要把它看成是两个。< /P> 因此,在检查
\0
时,可以直接检查
\n
的字节

如果要将
\n
(1个字符)替换为
\r\n
(2个字符)意味着,
str
应该有额外的内存,但在您的程序中没有额外的内存

char *a = "\n"; //This is one byte
char *b = "\\\n"; //This is two byte, 1st byte for '\' and 2nd byte for new line
char *c = "\\\r\n"; //Similarly this is three byte
char *c = "\r\n"; //Similarly this is two byte
以下所有转义序列字符都是C语言中的单字节字符

\n – New line
\r – Carriage return
\t – Horizontal tab
\\ – Backslash
\' – Single quotation mark
\" – Double quotation mark

<>所有C语言中的转义序列字符都是一个字符,只存储在一个字节的内存中,不要把它看成是两个。< /P> 因此,在检查
\0
时,可以直接检查
\n
的字节

如果要将
\n
(1个字符)替换为
\r\n
(2个字符)意味着,
str
应该有额外的内存,但在您的程序中没有额外的内存

char *a = "\n"; //This is one byte
char *b = "\\\n"; //This is two byte, 1st byte for '\' and 2nd byte for new line
char *c = "\\\r\n"; //Similarly this is three byte
char *c = "\r\n"; //Similarly this is two byte
以下所有转义序列字符都是C语言中的单字节字符

\n – New line
\r – Carriage return
\t – Horizontal tab
\\ – Backslash
\' – Single quotation mark
\" – Double quotation mark

\n
是ASCII码为10的单个字符的转义序列。它不是存储为两个字符
\
n
。它是。当您使用单个字符时,它无法正确解析它。这并没有解决我的问题。在十六进制编辑器中打开已编译的二进制文件,您将看到没有
\n