1

libc を使用せずに、改行文字 \n を \r\n である dos スタイルに変換しようとしています。

これが私の試みです。何が間違っていますか?

       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ただし、元のバッファーには、追加の文字を格納するための十分なスペースがありません。より大きなバッファを割り当てる必要があります。

第 2 に、UNIX スタイルのキャリッジ リターン文字は、2 つの個別\n文字として格納されません。これは、値が の 1 つの ASCII 文字であり0xA、エスケープ シーケンスを使用して表すことができます\n。したがって、現在の文字が改行文字かどうかを確認するには、次のように言いたいstrPtr[i] == '\n'

最後に、あなたが言うとき、あなたは古いバッファを上書きstrPtr[i-1] = '\r'しています. これにより、 , の前の文字\n( iinなど)が置き換えられHiます。

基本的に、出力用に 2 番目のバッファーを作成し、文字列を 1 文字ずつ出力バッファーにコピーします。文字に遭遇したとき\n、単一\nを新しいバッファにコピーする代わりに、 をコピーします\r\n

出力バッファーのサイズは、すべての文字が である入力文字列のケースを処理するために、入力バッファーのサイズの 2 倍に\nNULL ターミネーターの 1 を加えたサイズにする必要があります。\nただし、元の文字列の文字数を事前にカウントすることで、出力バッファーの最適なサイズを計算できます。

于 2013-02-10T05:09:34.880 に答える
1

C 言語のすべてのエスケープ シーケンス文字は 1 文字であり、1 バイトのメモリにのみ格納されます。2 文字とは見なさないでください。

したがって、をチェックしているように、バイトを直接チェックでき\nます\0

\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
于 2013-02-10T05:32:24.563 に答える
0

これをその場で行うことはできません。「\n」ごとに新しい文字 (「\r」) を追加しています。これは、文字列を展開する必要があることを意味します。最悪のシナリオは、すべての文字が '\n' である場合です。これは、文字列のサイズが 2 倍になることを意味します。したがって、元の文字列の 2 倍のサイズのバッファーを作成しましょう。

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はエスケープ シーケンスであり、1 文字で表されます。

コードは次のようになります。

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 に答える