1

How can I add different types in a table? Firstly I have to create a function in order to add the food that I ate (char), the calories (int) and the hour that I ate it (float) in a table with maximum size [100][4].

The only knowledge that I have and I can use for this project for my university is pointers and tables, NOT structures (which is the solution I was also thinking)

I've tried many things and the only thing that I did is to fill only the first column with the name of the food.

for (j=0;j<4;j++){
    if (j==0){
        printf ("Add your food:\n");
                    //char
        scanf("%s",&table[n][j]);
    }else if (j==1){
        printf ("Add calories:\n");
                    //int
        scanf("%d",&table[n][j]);

    }else if (j==2){
        printf ("Add the time you ate:\n");
                    //float
        scanf("%.2f",&table[n][j]);
    }else if (j==3){
        printf ("Kati\n");
    }
}

I expected my code to show all the data I filled but of course that doesn't work. So is there any solution to add different types in a table?

Werner Henze
  • 16,404
  • 12
  • 44
  • 69
Michael P.
  • 15
  • 1
  • 6

2 Answers2

1

add different types in a table? ... pointers and tables, NOT structures ..
... as char *table[100][4] ...

Save all data as strings. Convert the type/value into a string with enough information to reconstruct the type/value later.

#include <float.h>
#include <stdlib.h>
void table_add(char *table[100][4], size_t index, const char *food, int calories, float hour) {
  table[index][0] = strdup(food);
  char buf[42]; // large enough for a 128 bit `int`
  sprintf(buf, "%d", index);
  table[index][1] = strdup(buf);
  sprintf(buf, "%.*e", FLT_DECIMAL_DIG - 1, index);
  table[index][2] = strdup(buf);
  table[index][3] = NULL;  // Unclear what OP needs a 4th element for
}

Usage

#define FOOD_SIZE 50

char *table[100][4] = { 0 };

for (index = 0; index < 100; index++) {
  char food[FOOD_SIZE];
  printf ("Add your food:\n");
  scanf("%49s",food);

  int calories
  printf ("Add calories:\n");
  scanf("%d",&calories);

  float hour;
  printf ("Add the time you ate:\n");  // Unclear why OP is using float for `time`
  scanf("%f", &hour);

  printf ("Kati\n");

  table_add(table, index, food, calories, hour);
}

// now use the data somehow
index = ...
food = table[index][0];
calories = atoi(table[index][1]);
hour = atof(table[index][2]);
printf("Food:%s Calories:%d Time:%.2f\n", food, calories, hour);

// When done, free all allocations
for (index = 0; index < 100; index++) {
  for (j = 0; j < 4; j++) {
    free(table[index][j]);
  }
}

For details on FLT_DECIMAL_DIG - 1 in sprintf(buf, "%.*e", FLT_DECIMAL_DIG - 1, index); see Printf width specifier to maintain precision of floating-point value.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

Disclaimer This is not a general purpose solution, in nearly all cases there are better ways of doing such an exercise. However this is what your assignment restrictions call for

In C a pointer is allowed to alias any other type of pointer (though there are special restrictions when it comes to dereferencing such pointers), so you have to type pun your other types into your array (which is generally risky as you give up type safety). Modifying your code sample this would look like this (I have removed the loop and branching as I found them to hinder readability):

printf ("Add your food:\n");
// 50 is just to showcase, replace with actual value in your code
table[n][0] = malloc(50 * sizeof(char));
scanf("%s",table[n][0]);

printf ("Add calories:\n");
table[n][1] = malloc(sizeof(int));
scanf("%d",(int*)table[n][1]);

printf ("Add the time you ate:\n");
table[n][2] = malloc(sizeof(float));
scanf("%f",(float*)table[n][2]);

printf ("Kati\n");

Also make note of the changes I made to the scanf lines to make sure that the pointers passed in are of the actual correct types. Since you malloc all elements of the array you also need to remember to free them all at the end of your program to avoid memory leaks.

EDIT As commented by OP, table is defined as char* table[100][4]

UnholySheep
  • 3,967
  • 4
  • 19
  • 24
  • Hmmm.. Is the original a triple-pointer? `table[n][j] = malloc(50 * sizeof(char));`? You are allocating for `50-char` (or `int` or `float`) to every element? Not saying it is wrong, hard to tell without a declaration for `table`, just looks wonky. – David C. Rankin Jan 01 '19 at 18:54
  • @DavidC.Rankin OP commented that `table` is defined as `char* table[100][4]`. And that allocation is only for the "string" part (it looks a bit confusing due to the `for` loop, I'll rewrite it in a minute) – UnholySheep Jan 01 '19 at 18:56
  • That would explain. We have a 100x4 array of pointers to char. Could work. An array of 100 struct would probably be a more sane approach for the OP `:)` – David C. Rankin Jan 01 '19 at 18:57
  • @DavidC.Rankin fully agreed, but according to OP they are neither allowed to use `struct` or parallel arrays. Personally I am not entirely sure what the purpose of such an exercise is (which is why I added the **Disclaimer** at the start) – UnholySheep Jan 01 '19 at 19:03
  • In this case, wouldn't `int` be overwritten by `float`, since it occupies 4 bytes alone? Basically, if we have 4 bytes(as stated by OP), char->byte 0, int->byte 1,2,3,4(already past allocated memory address), float->bytes 5,6,7,8. This could result in segmentation fault. – Susmit Agrawal Jan 01 '19 at 19:11
  • @SusmitAgrawal no, I'm not assigning to the same pointer. And the type of pointer i assign the result of `malloc` to has no influence on where the memory is allocated – UnholySheep Jan 01 '19 at 19:14
  • @UnholySheep We have to create a menu which the user can add,modify,view all the meals that he has already eaten,search a specific one, sort all the meals and of course exit the program. These things have to be done in functions.Especially for Add function we have to input the food that we ate,the calories of it,and the hour that we ate it (on XX.YY type)that's why I was thinking to use float.All these data must be together in a single table of the sizes that I told you before. I also have to tell you that they didn't teach us anything about malloc so I cannot use it :/ – Michael P. Jan 01 '19 at 19:19
  • @MichaelP. I don't understand how my proposed solution causes a problem for your menu, it does exactly what you requested in the question. However if you cannot use `struct`, multiple arrays *or* `malloc` then your assignment is impossible to do. In fact the amount of things you can do with `char*` without `malloc` is very limited – UnholySheep Jan 01 '19 at 19:30