将char缓冲区强制转换为c结构

将char缓冲区强制转换为c结构,c,casting,struct,C,Casting,Struct,在下面的代码中,我期待另一个输出!: #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct _cust { char customerId[10]; char customerPhone[10]; char customerDep[4]; } cust; int main(int argc, cha

在下面的代码中,我期待另一个输出!:

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

typedef struct _cust {
        char    customerId[10];
        char    customerPhone[10];
        char    customerDep[4];
} cust;

int main(int argc, char **argv) {
        cust    *newCust;
        const char testChar[] = "11W35A5CT-012345678-CORP";

        newCust = (cust *)malloc(sizeof(struct _cust));
        newCust = (cust *)testChar;

        printf("CustomerId = %s\n", newCust->customerId);
        printf("CustomerPhone = %s\n", newCust->customerPhone);
        printf("CustomerDep = %s\n", newCust->customerDep);

        return 0;
}
我期望得到以下结果:

CustomerId = 11W35A5CT-
CustomerPhone = 012345678-
CustomerDep = CORP
有人能解释一下为什么会这样吗?谢谢

编辑:

为了避免在我的帖子中混淆,我在这里添加了调试此程序时的gdb跟踪:

(gdb) b main
Breakpoint 1 at 0x8048474: file name.c, line 11.
(gdb) run
Starting program: /home/evariste/src/customer_files/a.out 

Breakpoint 1, main (argc=1, argv=0xbffff2c4) at name.c:11
11  int main(int argc, char **argv) {
(gdb) n
13      const char testChar[] = "11W35A5CT-012345678-CORP";
(gdb) n
15      newCust = (cust *)malloc(sizeof(struct _cust));
(gdb) n
16      newCust = (cust *)testChar;
(gdb) n
21      printf("CustomerId = %s\n", newCust->customerId);
(gdb) print *newCust
$1 = {customerId = "11W35A5CT-", customerPhone = "012345678-", 
  customerDep = "CORP"}
这里我看到customerId=11W35A5CT-当我尝试printf时,我得到了整个字符串?

printf将输出,直到它到达\0,这表示字符串结束。任何连字符后面都没有\0,因此printf将从您给它的开始位置打印到testChar中的结束位置

此外,您泄漏了调用malloc时分配给您的内存。也许您想将字符串复制到结构中?

放弃malloc,在printf格式说明符中指定要打印的字符串的大小

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

typedef struct _cust {
    char    customerId[10];
    char    customerPhone[10];
    char    customerDep[4];
} cust;

int main(int argc, char **argv) {
    cust    *newCust;
    const char testChar[] = "11W35A5CT-012345678-CORP";

    newCust = (cust *)testChar;

    printf("CustomerId = %.*s\n", 
        sizeof(newCust->customerId), newCust->customerId);
    printf("CustomerPhone = %.*s\n", 
        sizeof(newCust->customerPhone), newCust->customerPhone);
    printf("CustomerDep = %.*s\n", 
        sizeof(newCust->customerDep),newCust->customerDep);

    return 0;
}

这有点过于简化,但希望它能说明发生了什么

typedef struct _cust {
        char    customerId[10];
        char    customerPhone[10];
        char    customerDep[4];
} cust;
编译器要做的就是把它当作一个24个字符的blob。假设blob的根是一个名为x的字符*。那么customerId只是x+0的别名,customerPhone是x+10的别名,customerDep是x+20的别名

因此,当您用字符串重写指针时,发生的情况是x=testChar

这意味着customerId是&testChar[0],customerPhone是&testChar[10],依此类推

问题在于,正如QuantumMechanical所说,printf和friends没有字符串范围的概念。C字符串刚刚开始,直到空字节。这意味着customId上的printf将从testChar[0]转到一个空字节,该字节将是testChar字符串的结尾

要想做你想做的事情,每个字符串的末尾都必须插入一个空字节,这意味着像这样的覆盖将无法工作。我相信你的覆盖可能会导致未定义的行为,但我不确定


或者你也可以按照mteckert的建议去做。

这里面有内存泄漏。您需要使用memcpy,而不仅仅是覆盖指针。还有,潜在的相关性:它不适用于这种情况,因为您只使用字符,但在使用结构解释原始数据时,您应该注意。@corbin:是的,我知道有内存泄漏,但这不是解释,当我在返回前释放时,它不会改变任何东西。@JamesMcLaughin:当我使用属性\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,为什么我没有三次相同的输出?阅读科尔宾的答案,这将解释为什么你没有三次看到相同的东西。简短版本-因为你每次都给printf一个不同的起始位置。谢谢你的回复,但我不明白为什么会发生这种情况,通常,当您将结构强制转换到内存区域时,通过移动每个元素大小的偏移量直到到达末尾,结构的所有组件都会分配到此区域。printf不关心结构组件。正如QuantumMechanical所说,它会一直打印到遇到空字符为止。感谢我了解编译器的工作,我编辑了我的帖子,并添加了gdb输出,请参考它。这种情况的发生是因为gdb知道它是一个字符[10]。printf没有。我不是100%相信:,我怎么才能提取这个文件的值?@iPadDevloperJr我不知道你为什么不相信。这就是C的工作原理。C中的指针只携带地址和类型以外的信息。你是什么意思?你怎么能提取?你读过mteckert的答案了吗?我希望能够像customerId=11W35A5CT-,customerPhone=012345678-,等等这样正确地进行映射。。。
typedef struct _cust {
        char    customerId[10];
        char    customerPhone[10];
        char    customerDep[4];
} cust;