tags:

views:

364

answers:

5

For an assignment, I have to declare a struct as follows:

struct Food
{
    char *name;
    int weight, calories;
} lunch[5] = {
    {
     "apple", 4, 100
    },
    { 
     "salad", 2, 80
    }
};

In my main, I am trying to ask the user for the rest of the inputs to fill the struct to print them out. I figure I would try to use malloc. Would I do something like this?

int main(void) 
{
    char *str1;
    printf("Please enter a food, weight, and calories of the food: ");
    scanf("%s", (char *)malloc(str1));
    return(EXIT_SUCCESS);
}
A: 

You should look at your course material, read the books on the reading-list, or ask your lecturer.

If you must do your own research online, you should perhaps try to understand this example and google for similar how-tos.

Generally, you shouldn't use scanf for parsing user input. Its much more straightforward and robust to use getline to retrieve a line of user input, then utilities such as strdup and atoi to extract your values, one per line rather than on the same line, and check for error values and such.

Will
We dont' have a book sadly.
Crystal
+2  A: 

Well ... Not quite.

You just pass the result of malloc() to scanf(), and that function won't return it, you lose the pointer. This is generally a bad idea. Also, investigate what argument malloc() expects, you're not doing it right.

Consider first allocating the memory, using a pointer variable to store it, and then passing the value of that pointer to scanf(). Hint: you already have the pointer variable, in your array.

Also, you shouldn't cast the return value of malloc() in C, and return is not a function, so it shouldn't have parenthesis around its value.

unwind
something more like this then?char *str1; if ((str1 = (char *)malloc(sizeof(char))) = NULL) { printf("Error allocating string 1"); } printf("Please enter a food, weight, and calories of the food: "); scanf("%s", str1);
Crystal
@Jonathan: That is far better, yes. But drop the cast of the return value, and think about how much memory you need to allocate. What is the value of sizeof (char), as a number? Is that many bytes enough? And don't you already have a pointer to use, in the definitions you showed?
unwind
The memory part confuses me. Doesn't malloc allocate the appropriate amount of memory?I thought the size of char was defined by its minimum of at least 8 bits? or 1 byte?
Crystal
char *str1 = malloc(sizeof(char *)); printf("Please enter a food, weight, and calories of the food: "); scanf("%s", str1);
Crystal
@Jonathan: Yes, sizeof(char) is 1 byte. A string consists of many characters, and you are only allocating space for 1. In fact, even a one-character string takes 2 bytes (1 for the actual character and 1 for the terminating '\0' character).
Chuck
@Jonathan: If the user enters "bananas", how many characters is that to store? What is the value of sizeof (char *)? You don't want to allocate space for the pointer, you already have that in your array.
unwind
+1  A: 

You should rather allocate space for a new instance of Food, then allocate space for name. If all allocations succeed, then you can start asking the user for data.

Konamiman
I think he actually already has 5 instances of "Food".
Lucas
As I have understood it, what he has is a Food array with space for 5 items, but containing only 2 items at first. But I may have got it wrong.
Konamiman
I am learing C at the moment, so I am less than sure here, but I think he has stuct "Food" which exists five times in the array "lunch". The first two Food instances of lunch are initialized and he wants to fill up the remaining three.
Lucas
You may be right. The code sample is not very clear anyway.
Konamiman
A: 

Here is a small example of how I would go about this. Unfortunatley I cannot test the code and I am learning C myself at the moment, but maybe this will give you some ideas. This would just initialize the instance at lunch[2]. So you should add some sort of loop to fill the other instances.

int main(void) 
{
    lunch[2].name = (char*) malloc(/*The size of the string you want for the 
                                        name of your food. Every character has 
                                        the size of one byte (+'\0' at the end)*/)



    printf("Please enter a name for your food: ");
    scanf("%s", lunch[2].name);
    printf("Please enter the weight of your food: ");
    scanf("%d", &lunch[2].weight;
    printf("Please enter calories of your food: ");
    scanf("%d", &lunch[2].calories);
    return EXIT_SUCCESS;
}
Lucas
A: 

getline, strtok, strdup, atoi

the rest is left as an exercise :-)

pm100