4

私はK&Rでエクササイズをしています:

次のタブストップまでのスペースに、入力のタブを適切な数のブランクに置き換えるプログラムdetabを記述します。

そしてこれは私がこれまでに持っているものです(ファイルのエラーチェックなし):

#include <stdio.h>
#define tab 2
#define MAX_LENGTH 1000
int main(int argc, char **argv)
{
    FILE *fp = fopen(argv[1], "r+");    
    int c, n;
    char buffer[MAX_LENGTH + 1];
    for (n = 0; n < MAX_LENGTH && (c = fgetc(fp)) != EOF; ++n) {
        if (c == '\t') {
            for (int x = 0; x < tab; ++x)
                buffer[n++] = ' ';
            --n;
        }
        else
            buffer[n] = c;
    }
    //buffer[n] = '\0';
    //rewind(fp);
    //fputs(buffer, fp);
    printf("%s\n", buffer);
    fclose(fp);
    return 0;
}

それはうまくいくようですが、なぜ\0最後に必要がなかったのか疑問に思います。ラッキーでしたか?

4

4 に答える 4

5

はい、あなたは幸運でした。この問題を回避するにfwriteは、ヌルターミネータを必要としないを使用することができます(書き込むバイト数を正確に指定するため)。

fwrite(buffer, 1, n, stdout);
于 2012-01-05T03:12:42.570 に答える
4

printf(...)特定の文字列に対して出力する (最大) 文字数を指定できます。

printf("%.*s\n", n, buffer);

printf(3)のセクション「精度」を参照してください。

オプションの精度。ピリオド ('.') の後にオプションの 10 進数文字列が続きます。10 進数文字列の代わりに、"*" [...] を記述して、精度が次の引数 [...] で指定されることを指定できます。これは int 型でなければなりません。[...] これにより、[...] s [...] 変換のために文字列から出力される最大文字数が得られます。

のライブ デモprintf ("%.*s\n", 5, "Hello, world!"): http://ideone.com/KHKLl

于 2012-01-05T03:46:06.027 に答える
2

次の方法でバッファを初期化できます。

memset(buffer, '\0', MAX_LENGTH + 1);

また、ヌル終了について心配する必要はありません。

于 2012-01-05T03:15:48.420 に答える
1

他の回答が指摘しているように、配列の適切な場所にヌルが含まれていたのは幸運でした。

次の短縮形を使用して、作成時に初期化できます。

char buffer[MAX_LENGTH + 1] = { 0 }; // all elements will be zero

これは、コンパイラが未指定のエントリをゼロで初期化するためであることに注意してください。

char buffer[MAX_LENGTH + 1] = { 'a' };

配列は次のようになります{'a',0,0,0....}

于 2012-01-05T03:30:07.663 に答える