char *指向一个int值,如何获取int值?

时间:2017-10-08 20:24:19

标签: c pointers

我从这样的文件中读取了4个字节:

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

当我打印尺寸时,它会写出大小必须为的正确值:

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

将打印200,这正是我之前在文件中写过的内容。

现在我怎样才能将值200作为int?

int s = *size;

不起作用。我该怎么办?

5 个答案:

答案 0 :(得分:2)

你在这里写的代码很不寻常:

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

read命令期望将第二个参数作为放置回读字节的位置的地址。在这里,你说“请用文件中的值覆盖构成指针的字节。”你这样做和写

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

这意味着“请将指针的字节解释为它们是一个整数,并打印出最终存在的任何值。”这是一种不寻常的方法,因为你基本上采用char *,它在逻辑上代表“在哪里寻找一个角色”,并将其视为一个数字。如果您忘记了这一点,然后尝试使用size,就好像它确实是一个指针,您几乎肯定会导致段错误并且行为未定义。

换句话说,您的char *并非指向为整数值。构成char *字面的字节是整数值。这就是解除引用它不起作用的原因;解除引用意味着“按照指针查看我们找到的内容”,但该指针并没有任何指向任何地方。

更糟糕的是,因为char *的大小和整数的大小不必相同(在64位系统上,您可能会发现sizeof(char *)为8并且sizeof(int)是4)使用printtf打印它可能会读取错误的字节数。

如果要读取整数,请创建一个整数变量,然后将指针传递给read

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

这说“请从我的size变量中的每个字节读取文件描述符中的一个字节,并将这些字节放入size占用的位置。”在这里,你对你正在读回来的内容是诚实的 - 你说把字节读成一个整数,这很好,因为你把它当作一个整数,你更准确地说要读{{1}如果系统上整数的大小不同,则为字节而不是4个字节。

如果您打算阅读原始字节,您可能甚至想要考虑使用类似sizeof(size)uint32_t的类型来更清楚地表明您需要特定的四个字节:

int32_t

答案 1 :(得分: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的指针取消引用。但是,如果没有看到文件格式的规范,我们就无法确定。这些四个字节中的每一个精确地代表什么?

答案 2 :(得分: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);
}

答案 3 :(得分:0)

我不知道我能做到:

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

然后我将文件中的书面大小作为int。

答案 4 :(得分:0)

取决于C便携性狂热的程度:

  1. 高级

    union {
      unsigned char c[sizeof(int)];
      int i;
    }c_i;
    
  2. 然后

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

    c_i.i包含整数。

    1. 低级别。就像现在使用的机器一样,严格的别名规则对IMO来说有点过于严格 - 指针惩罚工作在100%(可能除了char未对齐且uC不允许未对齐访问的情况除外)

      char *p = .....
      
      int *i = p;
      
    2. 在lynch之前,当指针投注调用UB时,请给出任何示例(除了我给出的那个)。除了愚蠢的废话,请:

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