-2

I'm trying to write a program that reads a file, prints what's in the file, add the contents of said file to an array, print from the array and then write to a file using the contents of the array.

My problem is when I try and print to the file, the array only prints the last entry in my char* array. Why does this happen?

Here's the problem code:

    char name[100];
    int age = 0;
    float bBalance = 0;

    char* namesArray[100];
    int ageArray[100];
    float floatArray[100];

    for (int i = 0; i < 100; ++i) 
    {
        namesArray[i] = (char*)malloc(100);
    }


    fptr = fopen("NTD.txt", "r");

    int lPtr = 1;

    if (fptr == NULL)
    {
        exit(1);
    }
    else
    {
        while (fscanf(fptr, "%99[^ ,], %d, %f", name, &age, &bBalance) != EOF)
        {
            namesArray[lPtr] = name;
            ageArray[lPtr] = age;
            floatArray[lPtr] = bBalance;

            printf("%s \n", namesArray[lPtr]);
            printf("%d \n", ageArray[lPtr]);
            printf("%f \n", floatArray[lPtr]);

            lPtr++;
        }

        fclose(fptr);
    }


    fptr = fopen("writeTo.txt", "w");

    if (fptr == NULL)
    {
        exit(1);
    }
    else
    {
        int i = 1;

        while (lPtr != 0)
        {
            fprintf(fptr, "%s,%d,%f \n",namesArray[i], ageArray[i], floatArray[i]);

            i++;
        }

        fclose(fptr);
    }

This is what the final file should look like:

Jane,50,420.69

Sam,20,50.00

Fabian,21,682.22

Zac,35,40000.00

Gabe,12,0.00

Shy,29,12.00

Charlot,99,0.00

Gen,15,64592.68

Guy,98,20000.00

Bill,60,1000000.00

This is what it actually looks like:

Bill,50,420.690002 

Bill,20,50.000000 

Bill,21,682.219971 

Bill,35,40000.000000 

Bill,12,0.000000 

Bill,29,12.000000 

Bill,99,0.000000 

Bill,15,64592.679688 

Bill,98,20000.000000 

Bill,60,1000000.000000 

If you need anything else, please let me know

yikesRobo
  • 25
  • 5
  • 1
    `fscanf` reads all names into the same `char name[100];` buffer, then `namesArray[lPtr] = name;` saves a *pointer* to that buffer in the array (and overwrites the pointer previously allocated). When you `fprintf` you get what was last read into the `name` buffer. User `strcpy` instead to copy each name. – dxiv Jan 17 '21 at 04:26
  • What sets `lPtr` between `while (lPtr != 0)` and then end of that loop? (one of those things where the scenery never changes....) Change the loop to `while (lPtr--)` In C, there is no need to cast the return of `malloc`, it is unnecessary. See: [Do I cast the result of malloc?](http://stackoverflow.com/q/605845/995714) – David C. Rankin Jan 17 '21 at 04:27
  • 1
    WRONG: `namesArray[lPtr] = name`; CORRECT: `strcpy(namesArray[lPtr], name);` You can't just "assign" strings in C. You need to COPY the string, with a function like [strcpy()](https://www.cplusplus.com/reference/cstring/strcpy) – paulsm4 Jan 17 '21 at 04:33

1 Answers1

3

namesArray[lPtr] = name;

Here is your problem. You make every element in namesArray point to name. name gets a new value read into it for each line, and in the end, it contains the last value read. All of the storage that you malloc'd in advance is leaked (it's still allocated, but you no longer hold any pointers to it, which means you can't use it and you can't free it).

You wanted to do strncpy(namesArray[lPtr], name, 100) to copy the characters from name to the already-existing char * in namesArray, instead of using = which copies the pointer itself, not the pointed-to values.

hobbs
  • 223,387
  • 19
  • 210
  • 288