2017-10-08 47 views
-2

我這樣從文件中讀取4個字節:char *指向一個int值,如何獲取int值?

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

當我打印尺寸,將其寫入正確的值的大小必須是:

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

將打印200,這正是之前我曾經在一個文件中寫過的東西。

現在我怎樣才能得到值200作爲一個int?

int s = *size; 

不起作用。我能做什麼?

+0

什麼是文件格式完全相同?你寫的四個字節代表什麼? –

+0

我打開這樣的文件: int fd = open(「file」,O_CREAT | O_WRONLY | O_APPEND,S_IRWXU); – Ehsan

+0

@Ehsan文件是一個字節流。如果你想寫一個多字節整數到一個文件,你需要一些方法來編碼該整數作爲一堆字節。不知何故,您已將整數編碼爲四個字節,以便每個字節代表該整數的一部分。您用來確定每個字節的值的準則是什麼? –

回答

2

,你在這裏寫的代碼是不尋常的:

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

read命令需要作爲第二個參數中,把字節位置的地址,回讀。在這裏,你說「請使用文件中的值覆蓋組成指針的字節」。你做到這一點,寫

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

,意思是「請解釋指針字節,好像他們是一個整數,並打印出最終被任何價值。」這是一種不尋常的方式,因爲你基本上採取了char *,它邏輯上代表「在哪裏尋找一個角色」,並把它看作是一個數字。如果您忘記了這一點,然後嘗試使用size就好像它確實是一個指針一樣,那麼幾乎肯定會導致段錯誤,並且行爲未定義。

換句話說,你的char *不是到一個整數值。構成您的char *的字節從字面上看是的整數值。這就是解除引用它不起作用的原因;解引用意味着「跟隨指針看看我們找到的是什麼」,但是這個指針並不是有意義地指向任何地方。

更糟的是,由於char *的大小和一個整數的大小不必是相同的(在64位系統上,你可能會發現sizeof(char *)是八sizeof(int)爲4),它是使用printtf將其打印出來可能會讀取錯誤的字節數。

如果你想讀一個整數,創建一個整數變量,然後將指針傳遞給它read

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

這是說「請在我的size讀取每個字節的文件描述符一個字節變量,並將這些字節放入由size佔用的位置。「在這裏,你對你正在閱讀的內容保持誠實 - 你說要將字節讀入一個整數,這很好,因爲你把它看作一個整數,而你更準確地說要讀取sizeof(size)字節,而不是4個字節,以防您的系統上的整數大小不同。

如果你正在閱讀原始字節的規劃,可能要甚至考慮使用像uint32_tint32_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。但是我們無法確定沒有看到文件格式的規範。 究竟是這四個字節中的每一個都代表什麼?

+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語言很陌生。使用open/read/write/close系統調用的正確方法是什麼? 1)define'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有點過於嚴格 - 100%指針夯實作品(也許除了情況下,當字符未對齊和uC不允許對齊訪問)

    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);