2017-10-08 11 views
-2

私はこのようなファイルから4バイト読み:char *はint値を指し、int値を取得する方法は?

printf("%d\n", size); 

正確である、200を印刷します:私はサイズを印刷するとき、それはその大きさがなければならない正しい値を書き込み

char *size; 
int rc = read(fd, &size, 4); 

を私が以前にファイルに書いたもの。

ここで、値200をintとしてどのように取得できますか?

int s = *size; 

は機能しません。私に何ができる?

+0

は正確にファイル形式は何ですか?あなたが書いた4バイトは何を表していますか? –

+0

私はこのようなファイルを開きます: int fd = open( "file"、O_CREAT | O_WRONLY | O_APPEND、S_IRWXU); – Ehsan

+0

@Ehsanファイルはバイトのストリームです。ファイルにマルチバイト整数を書きたい場合は、その整数を一束としてエンコードする必要があります。どういうわけか、各バイトがその整数の一部を表すように整数を4バイトとしてエンコードしました。各バイトの値を決定するために使用したルールは正確には何ですか? –

答えて

2

あなたはここに書いたコードは珍しいです:

char *size; 
int rc = read(fd, &size, 4); 

readコマンドは、その2番目の引数としてバイトを入れている場所の住所を期待しますそれは読み返している。ここでは、 "私のポインタを構成するバイトをファイルの値で上書きしてください"と言っています。あなたはそれと意味書き込み

printf("%d\n", size); 

行う「彼らは整数であるかのように、ポインタのバイトを解釈し、そしてなってしまうどのような値をプリントアウトしてくださいを。」これは、あなたが実質的にchar *を取っているので、これを行う珍しい方法です。「文字を探す場所」を論理的に表し、それを数字のように扱います。これを忘れて、実際にポインタであるかのようにsizeを試してみると、ほとんど確実にsegfaultが発生し、動作は未定義です。

つまり、char *ポイントの整数値になりません。 char *を構成するバイトは、文字通りです。の整数値です。このため、逆参照は機能しません。逆参照とは、「ポインタに従って見つけたものを見る」ことを意味しますが、そのポインタは意味のあるところを指していません。 char *の大きさや整数のサイズと同じである必要はありませんので、それはです(64ビットシステム上で、あなたはおそらく4であることを8とsizeof(int)するsizeof(char *)を見つけることができます)、

さらに悪いですprinttfを使用して印刷すると、間違ったバイト数が読み取られる可能性があります。

あなたは、整数を読み整数変数を作成し、readにそのポインタを渡したい場合は、次の

int size; 
int result = read(fd, &size, sizeof(size)); 

これは私のsizeに各バイトのファイル記述子から1つのバイトを読んでください」と言いますこれらのバイトをsizeが占める位置に配置します。ここでは、あなたが読んでいるものについて正直なことです。バイトを整数に読み込むと言うと、これは整数として扱うためです。より正確には、sizeof(size)バイトを読み込むと言っています。システムの整数のサイズが異なる場合は4バイトです。

あなたは生のバイトを読んで計画している場合は、あなたもより明確にあなたが、具体的に4バイトをしたいことを示すためにuint32_tまたはint32_tのようなタイプを使用して検討する必要があります。

uint32_t size; 
int result = read(fd, &size, sizeof(uint32_t)); 
+0

ありがとうございます、あなたの答えは非常に明確で、多くの助けがありました:) – Ehsan

1

正確なファイル形式によって異なります。おそらく:

int i = size[0] | 
    (size[1] << 8) | 
    (size[2] << 16) | 
    (size[3] << 24); 

は、それはまた次のようになります。

int i = size[3] | 
    (size[2] << 8) | 
    (size[1] << 16) | 
    (size[0] << 24); 

あなたはunsigned char代わりのcharへのポインタを通じて間接参照する必要があるかもしれません。しかし、ファイル形式の仕様を見ずにはわかりません。どのような正確にこれら4バイトのそれぞれを表しますか?

+0

私はちょっと驚いています:printf( "%d \ n"、サイズ)はOPの主張と同じように動作します... hm –

+0

@GiorgiMoniavaもしそうなら運がいいです。 –

+0

ええ、%dはポインタ(AFAIK)を期待していません。 –

0

あなたのコードがポータブルになりたい場合は、ここにファイルにあなたの整数を保存するための別のアプローチがあります...

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

// store an integer value into comma-separated, 
// human-readable text file and retrieve the value 
int main() 
{ 
    FILE *fp; 
    int value = 400; 
    int read_value = 0; 

    if ((fp = fopen("test-int-store", "w+")) == NULL) { 
     perror("fopen:"); 
     exit(1); 
    } 

    if (!fprintf(fp, "%d,\n", value)) { 
     perror("fopen:"); 
     exit(1); 
    } 

    rewind(fp); 

    if (!fscanf(fp, "%d,\n", &read_value)) { 
     perror("fopen:"); 
     exit(1); 
    } 

    printf("read_value=%d\n", read_value); 

    fclose(fp); 
} 
+0

私はオープン/リード/ライトのシステムコールしか使用できません。 – Ehsan

0

私は私がちょうどできることを知りませんでした:

int size; 
int rc = read(fd, &size, 4); 

し、私はintとしてファイルに書かれたサイズを持って戻ってきた。

+0

これがうまくいくと運が悪いだけです。ここでも、これはCコードを記述するための純粋な方法ではありません。 –

+0

@DavidSchwartz、私は受け入れる、私は非常にC言語に新しいです。オープン/リード/ライト/クローズのシステムコールのみを使用してこれを行う正しい方法は何ですか? 1) 'int size = 200'を定義します。 2)' size'の値を空のファイルに書き込みます。 3)あとでそのファイルに書いた内容を読み返してください。 4)読んだものからサイズの値を取得します。 – Ehsan

+0

私の答えを見たり、 'ntohl'のような関数の使い方を学んでください。または、数字をテキストに保存します。 –

0

Cポータビリティ狂信のレベルに応じて:

  1. ハイレベル

    union { 
        unsigned char c[sizeof(int)]; 
        int i; 
    }c_i; 
    

、次いで

char *p; 

for(int i = 0; i < sizeof(int); i++) 
    c_i.c[i] = (unsigned char *)(p + i); 

c_i.iは整数を含んでいます。

  1. 低レベルです。今日では、厳密なエイリアシング規則を使用マシン上のようIMO少し厳しすぎる - (文字が整列されていないとUCは非整列アクセスを許可しないとき多分状況を除く)ポインタパンニングも100%で動作する前に

    char *p = ..... 
    
    int *i = p; 
    

リンチは、ポインティング・ペニングがUBを呼び出すときに、私が与えたものを除いて、例を挙げてください。してください愚かなナンセンスなものを除い:

void foo(int *i, long long *l) { *i = 10; *l = 20; printf("%d\n",i); } 

char k[100]; 

foo (k,k); 
関連する問題