将char缓冲区转换为c结构

时间:2012-04-01 00:31:24

标签: 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, 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-012345678-CORP
CustomerPhone = 012345678-CORP
CustomerDep = CORP

我期待这个输出:

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时,我得到了整个字符串?

3 个答案:

答案 0 :(得分:6)

printf()将输出,直到它到达\0,表示字符串的结尾。在任何连字符之后没有\0,因此printf()将从您给它的开始位置打印到testChar的结尾。

此外,您泄露了为您分配的malloc号码的内存。也许你想字符串复制到struct?

答案 1 :(得分:2)

这有点过于简化,但希望它能说明正在发生的事情。

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

编译器将对此做什么假装它是一个24个字符的blob。假设blob以一个名为x的char *为根。然后customerId只是x + 0的别名,customerPhone是x + 10的别名,customerDep是x + 20的别名。

所以,当你用字符串写指针时发生的事情是x = testChar。

这意味着customerId是&amp; testChar [0],customerPhone是&amp; testChar [10]等等。

问题在于,如QuantumMechanic所说,printf和朋友没有字符串范围的概念。 C字符串刚刚开始直到空字节。这意味着customId上的printf()将从testChar [0]开始,直到它到达一个空字节,这将是testchar字符串的结尾。

要做你想做的事情,每个字符串都必须在它的末尾插入一个空字节,这意味着你的叠加不会起作用(我相信你的叠加可能导致未定义的行为,但我是不确定)。

(或者你可以像mteckert建议的那样。)

答案 2 :(得分:0)

抛弃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;
}