1

我正在尝试将换行符 \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”

4

4 回答 4

4

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

其次,UNIX 风格的回车符不存储为两个单独的\n字符。它是一个值为 的 ASCII 字符0xA,可以使用转义序列来表示\n。所以要检查你当前的字符是否是换行符,你想说strPtr[i] == '\n'

最后,当您strPtr[i-1] = '\r'. 这将替换 ,之前的字符\n(例如iin Hi)。

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

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

于 2013-02-10T05:09:34.880 回答
1

C语言中所有的转义序列字符都是一个字符,只存储在一个字节的内存中,不要认为它是两个。

\n因此,您可以在检查时直接检查字节\0

如果你想用(2个字符)替换\n(1\r\n个字符)意味着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
于 2013-02-10T05:32:24.563 回答
0

您不能就地执行此操作。您正在为每个 '\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);
于 2013-02-10T05:14:11.653 回答
0

您的\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.
于 2013-02-10T05:14:49.260 回答