1

I keep getting 4 "Passing argument 1 of strcpy makes pointer from integer without a cast" error message each time I am trying to write a string to a dynamically allocated array of strings. I know that it has to do with my strcpy call obviously, and that it's a type mismatch issue somewhere, but I need a little assistance on this please.

/* ---- LIBRARIES ---- */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* ---- PROTOTYPES ---- */
int readFx(char** arr);

/* int sortFx(char** arr, int arg2);
int printFx(char** arr, int arg2); */

int freeFx(char** arr, int cnt);
char* getToken(char arr1[], int loc);
void makeRoom(char*** t, int size);

/* ---- MAIN ---- */
int main(void)
{
    char** pntrArr;
    char* fileText;
    int iniArrSize = 10;
    int recCnt = 0;

    /* array to store addresses of arrays forming the rows */
    pntrArr = malloc(iniArrSize * sizeof(char*));

    recCnt = readFx(pntrArr);
    sortFx(pntrArr, recCnt);
    /* printFx(pntrArr, recCnt); */
    freeFx(pntrArr, recCnt);

    return;
}

/* ---- FUNCTIONS ---- */

int readFx(char** arr)
{
    /*
    input: csv file of string arrays
    output: count of records received
    purpose: read file, store values in array and populate pointer array
    */

    char buffer[350];
    char temp[350];
    char*** reallocTemp;
    char* token;
    int counter, index;
    int subLoc = 3;
    int enrLoc = 8;
    int arrSize = 10;

    /* Clear headers */
    fgets(buffer, sizeof(buffer), stdin);

    counter = 0;

    /* While file stream is not null */
    while (fgets(buffer, sizeof(buffer), stdin) != NULL)
    {
        /* Populate array within array if pntr arr has room */
        if(counter <= arrSize)
        {
            /* buffer copy*/
            strcpy(temp, buffer);
            index = 0;

            /* create array for token values */            
            arr[counter] = malloc(10 * sizeof(char));

            /* Get first token */
            token = getToken(temp, subLoc);

            strcpy(arr[counter][index],token);
            index++;

            /* Get second token */
            token = getToken(temp, enrLoc);

            strcpy(arr[counter][index], token);

            counter++;
        }
        else
        {
            /* Reallocate memory due to necessary expansion */
            makeRoom(&arr, arrSize);

            /* Realloc was successful */
            if(temp != NULL)
            {
                arrSize = arrSize * 2;

                /* Print Reallocation info */
                printf("reallocating to %d", arrSize);

                /* Populate values for current buffer now that you have realloc'd */ 

                /* buffer copy*/
                strcpy(temp, buffer);
                index = 0;

                /* create array for token values */
                arr[counter] = malloc(10 * sizeof(char));

                /* Get first token */
                token = getToken(temp, enrLoc);

                strcpy(arr[counter][index], token);
                index++;

                /* Get second token */
                token = getToken(temp, subLoc);
                strcpy(arr[counter][index], token);

                counter++;
            }
            else
            {
                printf("unable to reallocate\n");
                exit(1);
            }
    }

    return counter;

}


char* getToken(char arr1[], int loc)
{
    /*
    input: string array & location of desired string
    output: string of token at position
    purpose: grab string (char*) of certain position in given array
    */

    int loopCnt;
    char* del = ",\n";

    /* Grab first token */
    char* token = strtok(buffer, del);

    /* Loop through array to grab value at given location */
    for(loopCnt = 1; loopCnt < loc; loopCnt++)
    {
        token = strtok(NULL, del);
    }

    return token;
}

int freeFx(char** arr, int cnt)
{
    int i;

    for(i = 0; i < cnt; i++)
    {
        free(arr[i]);
    }

    free( arr ); 
    return 0;
}

void makeRoom(char*** t, int size)
{
    *t = realloc(*t, size * 2  * sizeof(char*));
}
Dpry12
  • 105
  • 8
  • 1
    `arr[counter][index]` is a `char`. Please explain what you expect to happen when you pass a single character as the first argument of strcpy ? – M.M Mar 11 '16 at 04:15
  • Ok, thank you @M.M for pointing this out. I have changed the instantiation to be `arr[counter] = malloc(10 * sizeof(char*))` since I was trying to write a string of chars to a char. Now that this is corrected, I am still getting the strcpy errors, though. Or did I still miss what you are referring to? – Dpry12 Mar 11 '16 at 04:19
  • `arr[counter] = malloc(10 * sizeof(char*))` allocates too much memory and doesn't address the problem. Do you understand that `arr[counter][index]` is a single char? – M.M Mar 11 '16 at 04:24
  • @M.M I do now, but did not prior to your comment. I need to change that to a string, what would be the best approach? – Dpry12 Mar 11 '16 at 04:26
  • @M.M, would it just be `arr[counter]` instead of `arr[counter][index]` ? – Dpry12 Mar 11 '16 at 04:33
  • @M.M, after playing with it, I changed it to `arr[counter] = (char *)malloc(10 * sizeof(char))` and the strcpy's to `strcpy(arr[counter], token);` and this seems to have cleared these errors – Dpry12 Mar 11 '16 at 04:46

1 Answers1

0

From code :

strcpy(arr[counter][index],token);

arr[counter][index] refers to the single character of the array, so please use arr[counter] instead of that (which is pointer to the dynamically allocated block),

so that you can copy the string to that dynamic array.

Adding extra details, if you use strcpy as below,

strcpy(arr[counter][index],token);

Still the copy is done but, not in the correct location,

Suppose arr[counter] holds the address of a char pointer which is 1000.

So strcpy(arr[counter][index],token); will copy the string in the address 1000 + index.

strcpy(arr[counter],token) will copy the string in the address 1000

Hope this is helpful.

Ash
  • 176
  • 1
  • 11
  • Thank you so much @Ash! Here is what I did I: changed it to `arr[counter] = (char *)malloc(10 * sizeof(char))` and the strcpy's to `strcpy(arr[counter], token);` and this seems to have cleared these errors. Now I am getting an "Error: expected declaration or statement at end of input." any ideas on that? Also, how can I access the two different values at arr[counter] since I am storing two values in this array? – Dpry12 Mar 11 '16 at 04:48
  • 1
    In readFx you have missed to close the brace for else part line . no 85, check that once – Ash Mar 11 '16 at 05:02
  • "Also, how can I access the two different values at arr[counter] since I am storing two values in this array?" Here the arr is a double pointer, so arr[counter] represents the starting address of the char array, and arr[counter][index] represents the character in the string. what do you mean by " storing two values in this array " – Ash Mar 11 '16 at 05:03
  • In the code, I am tokenizing twice, using the arr[counter] array to hold both tokens...is this not possible? – Dpry12 Mar 11 '16 at 05:07
  • Also, I have updated the coding [here](https://drive.google.com/file/d/0B3JyOtVloC3-OEJWam50dV9STVk/view?usp=sharing) to reflect the updates I have made. I need to solve for the issue above this comment, and a segmentation fault – Dpry12 Mar 11 '16 at 05:10
  • you can't copy two strings in the same memory area, so use another array to copy that. As the arr[counter] holds the latest copied string then the first token will be lost – Ash Mar 11 '16 at 05:11
  • Ok, dummy move on my part. So what I am trying to do is take in a csv file, and in column 4 is one value I want, column 9 is the other value. and along the way, dynamically expanding to double the size based upon memory needs. What would you say the best approach to this would be, store the entire row, and then tokenize? Or would tokenizing first, and then storing be better? – Dpry12 Mar 11 '16 at 05:22
  • I would prefer you to take the entire row first and tokenize the row and store the tokenized strings in another two dimensional array( dynamically preferred when memory constraints are considered), just because for easier code readability – Ash Mar 11 '16 at 05:28
  • Ok, taking your advice, I am going to do that, but I am going to store the col 4 values in one array and the col 9 values in another. Does this solve for the segmentation fault I am getting? Or no? Btw, thank you for being an awesome resource! – Dpry12 Mar 11 '16 at 05:37
  • Welcome, Yeah you can use two different arrays to store, but no idea about the segmentation fault, try to complete coding part and if segmentation fault occurs, then by using printf after every memory operations, then you can come to know where the error and you can easily solve it – Ash Mar 11 '16 at 05:47
  • ok, here is my updated code now [LINK](https://drive.google.com/file/d/0B3JyOtVloC3-a2hUaUpnNmhnQVE/view?usp=sharing)...I am getting the segmentation fault on the second call to getToken, any idea why? – Dpry12 Mar 11 '16 at 06:21
  • Hi Dpry12, hope you have found the solution,this is my solution As strtok will modify the first argument, but still you are again using the same string in strtok function for second time. Solution is to take a backup of the string which is needed to tokenize second time for other delimiter – Ash Mar 15 '16 at 11:12