C程序为结构动态分配内存然后将memcpy输入到

时间:2016-11-09 01:06:44

标签: c

需要一些帮助大师。我是C的新手,试图了解如何解决这个问题。 好的,所以我需要为输入NAME(加上一个空终止符)分配确切的内存量,并将指针存储在数组内的分配位置。使用memcpy将NAME复制到已分配的内存中,int值可以直接存储到数组元素中结构的相应成员中。 任何帮助,将不胜感激。 欢呼声。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ITEMS 5

int main(void)
{
    struct Inventory
    {
        char *name, int year, int amount;
    } brand[ITEMS] = { {"chevy", 2014, 12}, {"acura", 2016, 22} };

    struct Inventory *ptr, s;
    ptr = &s;
    int count, num;

    for (count1 = 0; count < ITEMS; count1++)
    {
        printf("Enter a brand of automobile, year, and count of the vehicle with a space in between:\n");
        scanf("%s%d&d", &ptr->name, &ptr->year, &ptr->amount);

        if ( (ptr = (char *)malloc(sizeof(char)) == NULL))
        {
            fputs("Out of memory\n", stderr);
            exit(EXIT_FAILURE);
        }
        /* memcpy */
        printf("%s\t%d\t%d\n", ptr->name, ptr->weight, ptr->calories);
        free(ptr);
    }
    return 0;
}

2 个答案:

答案 0 :(得分:0)

结构指针+整数: PTR +计数。

非初始化计数,使用count&amp;递增另一个变量:count1 ++ for(count1 = 0; count&lt; ITEMS; ++ count1)

纠正这些错误。

答案 1 :(得分:0)

您的代码中会有许多问题。虽然您可以自由地为name分配存储空间,但如果您还将字符串文字分配给brand的前2个元素,则会使事情变得复杂。然后,您将拥有混合文字和已分配的内存块,您必须跟踪这些内存块,以便了解以后需要释放的内容。

此外,使用scanf读取多个值时,最好将整行读入fgets的缓冲区,然后调用sscanf来解析值。将解读与解析分离是有道理的有很多原因。

另外,如果名称很短,那么为什么不使用数组并完全取消动态分配呢?出于您的示例的目的,您将文字指定给前两个,这也解决了您需要free d的问题以及如果您尝试释放它们将 segfault

我在下面的评论中包含了更多内容。仔细看看,如果您有其他问题,请告诉我们:

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

enum { ITEMS = 5, MAXN = 32, MAXC = 256 };

typedef struct {
    char name[MAXN];
    int year, amount;
} inventory;

int main (void) {

    /* you do not want to mix string literals below for 'name' with allocated
     * blocks of memory also used for 'name' because the logic to free the allocated
     * blocks would be unnecessarily complicated. (e.g., some 'name's allocated,
     * some holding literals) Keep your code consistent. If the length of name is
     * reasonably short, just use an array.
     */
    inventory brand[ITEMS] = { {"chevy", 2014, 12}, {"acura", 2016, 22} };
    int num = 2;

    while (num < ITEMS) {

        char buf[MAXC] = "";
        /* no need for ptr, it's up to you, brand[num] with dot notation is fine */
        inventory *ptr = &brand[num];
        printf ("Enter a brand of automobile, year, and count "
                "of the vehicle with a space in between:\n");
        /* if name is a pointer, you must allocate space before calling scanf
         * (unless using the 'm' modifier ('a' for older scanf and windoze) and
         * you then provide a pointer-to-pointer-to-char) Using an array avoids
         * that problem wit name.
         */
        if (!fgets (buf, MAXC, stdin) ||
            sscanf (buf, " %s %d %d", ptr->name, &ptr->year, &ptr->amount) != 3) {
            fprintf (stderr, "error: invalid input.\n");
            continue;
        }

        /* allocating 1-char for ptr is somewhat pointless here */
        // if ( !(ptr = malloc (sizeof(char)) == NULL)) {
        /* you would allocate the sizeof one struct, or just s, however using
         * an array for name makes allocation unnecessary.
         */
        // if (!(ptr = malloc (sizeof s))) {
        //     fputs ("Out of memory", stderr);  /* fputs adds a newline */
        //     exit (EXIT_FAILURE);
        // }

        /* memcpy -- WTF?? (there is no memcpy here, what is weight, calories?) */
        // printf("%s\t%d\t%d\n", ptr->name, ptr->weight, ptr->calories);

        /* you probably want */

        // free(ptr); (no allocation, no free required
        num++;
    }

    /* now lets see if it worked */
    for (int i = 0; i < num; i++)
        printf ("\n name   : %s\n year   : %d\n amount : %d\n",
                brand[i].name, brand[i].year, brand[i].amount);

    return 0;
}

(最后,为C ++保留 MixedCase 变量名.C样式通常更喜欢小写,保留常量和宏的大写。虽然样式完全取决于你,但是一种奇怪的样式电报在达到任何细节之前,你的代码很多很多)

示例使用/输出

$ ./bin/inventory2
Enter a brand of automobile, year, and count of the vehicle with a space in between:
ford 1968 7
Enter a brand of automobile, year, and count of the vehicle with a space in between:
foo bar
error: invalid input.
Enter a brand of automobile, year, and count of the vehicle with a space in between:
mazda 2007 9
Enter a brand of automobile, year, and count of the vehicle with a space in between:
toyota 2012 4

 name   : chevy
 year   : 2014
 amount : 12

 name   : acura
 year   : 2016
 amount : 22

 name   : ford
 year   : 1968
 amount : 7

 name   : mazda
 year   : 2007
 amount : 9

 name   : toyota
 year   : 2012
 amount : 4