0

I am still new to C. I am reading from a file stock.dat:

I0001|Meat Pie|Yummy Beef in Gravy surrounded by pastry|3.50|50
I0002|Apple Pie|Delicious Stewed Apple in a Yummy Pastry envelope|3.00|20
I0003|Lemon Cheesecake|A delicious, 1/8 size slice of cheesecake|4.00|10
I0004|Lemon Meringue Pie|This pie has a tender pastry crust, a tangy lemon filling and a topping of soft, fluffy meringue.|3.00|20
I0005|Lemon Tart|A delicious lemon butter tart with a pastry base|3.75|12

I am tokenising it using the appropriate delimiters, then using memcpy to save to the struct. However, I am having problems with data.price.dollars, data.price.cents, and data.onHand.

I keep getting this warning: passing argument 1 of ‘memcpy’ makes pointer from integer without a cast [enabled by default]

data.id, data.name and data.desc does not display any warning.

I understand memcpy takes 2 pointers. But What I don't understand, is HOW i can make data.price.dollars/cents and data.onHand into a pointer? I have hit a wall here.

If I'm on the completely wrong track, I would really be thankful if someone could point me in the right direction.

This is my code:

Boolean loadStock(VmSystem * system, const char * fileName)

    {

        char *j; /*To convert Chars to numbers*/    
        char line[MAX_LEN_LINE];
        FILE * fPointer; /*file pointer*/
        Stock data;
        List * list = system->itemList;

        fPointer = fopen(fileName, "r"); /*open the file which is 2nd in the array of string which should be the data file, and "r" read it*/


        while(!feof(fPointer)) /*file end of file*/
        {

            fgets(line, MAX_LEN_LINE, fPointer);


            /*Tokenise*/    
            memcpy(data.id, strtok(line, STOCK_DELIM), ID_LEN+NULL_SPACE);
            memcpy(data.name, strtok(NULL, STOCK_DELIM), NAME_LEN+NULL_SPACE);
            memcpy(data.desc, strtok(NULL, STOCK_DELIM), DESC_LEN+NULL_SPACE);
            memcpy(data.price->dollars, (int)strtol(strtok(NULL, "."), &j, 10), 2);
            memcpy(data.price->cents, (int)strtol(strtok(NULL, "|"), &j, 10), 2);
            memcpy(data->onHand, (int)strtol(strtok(NULL, " "), &j, 10), 2);


            addToLinkedList(list, &data);


        }

        fclose(fPointer);

        return FALSE;
    }

    typedef struct stock
    {
        char id[ID_LEN + NULL_SPACE];
        char name[NAME_LEN + NULL_SPACE];
        char desc[DESC_LEN + NULL_SPACE];
        Price price;
        unsigned onHand;
    } Stock;
Brown Bear
  • 19,655
  • 10
  • 58
  • 76
  • 2
    Read about [why `while(!feof(file)) {}` is always wrong](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – ad absurdum Oct 20 '17 at 04:36
  • `data` is not a pointer, so why `data->onHand`? Also, `Price` is not defined in the posted code; is `Price` a pointer type? If not, why `data.price->dollars` and `data.price->cents`? Do you instead need `memcpy(&data.price.dollars...)`? These questions would be addressed by a [MCVE].... – ad absurdum Oct 20 '17 at 04:43
  • typedef struct price { unsigned dollars; unsigned cents; } Price; – Ash Ketchum Oct 20 '17 at 04:58
  • Sorry, first time using S.O uhm so that above comment of mine, is the other struct for price – Ash Ketchum Oct 20 '17 at 04:59
  • Thanks David. I will read that recommendation now. – Ash Ketchum Oct 20 '17 at 04:59
  • What weird's me out is it doesn't show that warning for data.id. – Ash Ketchum Oct 20 '17 at 05:14
  • by the way I changed '->' to '.' – Ash Ketchum Oct 20 '17 at 05:15
  • `data.id` is an array, which decays to a pointer to `char` in this context.... What is the warning you are expecting? – ad absurdum Oct 20 '17 at 05:16
  • 1
    yes memcpy(&data.price.dollars...) removed the warning. Thank you! :D – Ash Ketchum Oct 20 '17 at 05:19
  • after entering gdb, and running stock.dat I get this: – Ash Ketchum Oct 20 '17 at 05:26
  • Program received signal SIGSEGV, Segmentation fault. 0x0000000000400c75 in loadStock (system=0x603010, fileName=0x7fffffffe638 "stock.dat") at vm_options.c:82 82 memcpy(data.name, strtok(NULL, STOCK_DELIM), NAME_LEN+NULL_SPACE); (gdb) backtrace #0 0x0000000000400c75 in loadStock (system=0x603010, fileName=0x7fffffffe638 "stock.dat") at vm_options.c:82 #1 0x0000000000400a17 in main (argc=2, argv=0x7fffffffe3a8) at vm.c:17 (gdb) frame 1 #1 0x0000000000400a17 in main (argc=2, argv=0x7fffffffe3a8) at vm.c:17 17 loadStock(system, argv[1]); (gdb) – Ash Ketchum Oct 20 '17 at 05:26
  • `memcpy()` is good to copy an arbitrary number of bytes which even might be varying at run-time. For basic types like `char`, `int`, `float`, `double`, just use the assignment operator `=`. For strings with zero termination, there are special string functions (e.g. `strcpy()`) available. If you `memcpy()` a basic type like `int` then its at least a good idea to use `sizeof(int)` for the 3rd parameter. I don't say its impossible but I would wonder if `int` on your platform has 2 bytes only... – Scheff's Cat Oct 20 '17 at 06:19
  • 1
    `memcpy(data.price->cents, (int)strtol(strtok(NULL, "|"), &j, 10), 2);` is a bad idea. `memcpy()` takes a destination _pointer_, a source _pointer_, and the length in bytes. `(int)strtol(strtok(NULL, "|"), &j, 10)` provides a return value which is _not addressable_ (but only assignable). Thus, this will/must fail definitely. Ah yepp, it did: "SIGSEGV". – Scheff's Cat Oct 20 '17 at 06:25
  • And the above is still true even if you corrected the first argument to provide the destination pointer: `memcpy(&data.price->cents, (int)strtol(strtok(NULL, "|"), &j, 10), 2);`... – Scheff's Cat Oct 20 '17 at 06:28
  • 1
    Assuming you try to learn how to use `memcpy()`... You have to _store_ the result of `strtol()` to make it applicable to `memcpy()`. e.g.: `int tmp = (int)strtol(strtok(NULL, "|"), &j, 10); memcpy(&data.price->cents, &tmp, sizeof(int));`. But actually I still would prefer `data.price->cents = (int)strtol(strtok(NULL, "|"), &j, 10);`. The latter will even work if `data.price->cents` has a compatible type (like e.g. `double`, `float`, or `short`) as the compiler will now silently insert the proper conversion. – Scheff's Cat Oct 20 '17 at 06:34
  • Thanks guys. Really helpful. Much appreciated :) – Ash Ketchum Oct 22 '17 at 02:56

0 Answers0