2017-10-08 119 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);