0

ファイルを開いて読み取るための非常に基本的な C スニペットを次に示します。

  int fd = open("test.txt",O_RDONLY);
  char buf[128];
  int reader = read(fd,buf,128);
  int i;
    for (i=0;i<strlen(buf);i++)
    {
        printf("%i: I read: %c", i, (int)buf[i]);
    }

これらの標準ヘッダーも含めています。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

このコードは C で正常に動作し、Objective-C は CI のスーパーセットであるため、Obj-C でも正常に動作すると予想されます。しかし、代わりに、次のようなすべてのガベージ データを取得しています。

0: I read: –
1: I read: *
2: I read: :

なんで?

4

4 に答える 4

2

あなたのopen呼び出しはおそらく失敗しています。ファイルへのフル パスを指定してみて、エラー チェックを使用してください。

于 2009-11-28T22:19:13.273 に答える
2

read() からの出力バッファで strlen を使用しないでください - null で終了していません。

于 2009-11-28T22:13:21.807 に答える
1

これまでの回答を要約し、私自身の観察を追加します。

とからの戻り値を確認する必要がopen()ありread()ます。それらが失敗した場合、やみくもに続行し、ゴミを印刷することになります。

read()読み取った文字数を返します。エラーの場合は -1 を返します。バッファをヌルで終了しないためstrlen()、読み取ったデータの量を見つけるために使用するのは間違っています。

strlen()反復ごとに再評価するため、ループ テスト条件に呼び出しを配置し​​ないでください。

ステートメント内のbuf[i]toのキャストは不要です。などの可変引数関数(つまり、 を構成するすべての引数) への追加の引数は、次のようにデフォルトの引数昇格を受けます。intprintfprintf...

  • chars、 s、およびそれらの署名されていない対応するものはsshortに昇格しますint
  • floatdoubles がsに昇格

キャストがなければ、buf[i]暗黙のうちにとにかくに昇格されるintため、キャストを追加すると、コードを読む人にとってコードがより混乱します。

したがって、コードは次のようになります。

int fd = open("test.txt",O_RDONLY);
if(fd < 0)
{
    fprintf(stderr, "open failed: %s\n", strerror(errno));
    return;
}
char buf[128];
// It's better to use sizeof(buf) here, so we don't have to change it in case we
// change the size of buf.  -1 to leave space for the null terminator
int reader = read(fd,buf,sizeof(buf)-1);
if(reader < 0)
{
    fprintf(stderr, "read failed: %s\n", strerror(errno));
    close(fd);
    return;
}
buf[reader] = 0;  // add null terminator for safety
int i;
for (i=0; i < reader; i++)
{
    printf("%i: I read: %c", i, buf[i]);
}
于 2009-11-28T22:37:25.870 に答える
1

まず、for ステートメントで strlen() 呼び出しを行うことは非常に悪い習慣です... コンパイラが最適化しない限り、ループは Order N**2 時間で実行されます。

次に、バッファーがゼロで終了していることをどのように確認しますか? ここで、有効ではない可能性のある仮定を立てています。バッファーのサイズ (128) がわかっているので、BUFSIZE などの定数を使用する必要があり、ループ内の条件は 'i < BUFSIZE' である必要があります。

3 番目に、buf[i] に格納されている文字値を int にキャストし、それを char として出力しています。明らかに、Objective-C はデスクトップ C コンパイラと同じ方法でこれを行うわけではありません。とにかく、これは言語で弱く定義されています。buf[i] を int にキャストせずに参照する方がよいでしょう。これがあなたの問題があると確信しています。

于 2009-11-28T22:24:03.920 に答える