-1

I have to read from a file line by line and add those lines into a char array. I need to keep the array const and also pass it as a const pointer.

#include<stdlib.h>
#include<stdio.h>
#include<string.h>

void takeAction(const char **charArray) {

    for (int i = 0; i<2; i++) {
        printf("%s\n", charArray[i]);
    }

}

int main(int ac, char **av)
{
    
    // Read patterns from file

    FILE *fp;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    int counter = 0;

    const char *charArray[1000];

    fp = fopen(av[1], "r");
    if (fp == NULL) {
        fprintf(stderr, "%s File could not be opened \n", av[2]);
        return 1;
    }
    while ((read = getline(&line, &len, fp)) != -1)
    {
        
        charArray[counter] = malloc(sizeof(char)*(read+1));
        memcpy(charArray[counter], line, read);
        counter++;

        if (counter == 2) {
          counter = 0;
          takeAction(charArray);
        }

    }
    fclose(fp);
    return 0;
}

compilation error

 temp.c: In function ‘main’: temp.c:42:16: warning: passing argument 1
 of ‘memcpy’ discards ‘const’ qualifier from pointer target type
 [-Wdiscarded-qualifiers]
          memcpy(charArray[counter], line, read);
                 ^~~~~~~~~ In file included from temp.c:3:0: /usr/include/string.h:42:14: note: expected ‘void * restrict’ but
 argument is of type ‘const char *’  extern void *memcpy (void
 *__restrict __dest, const void *__restrict __src,

Execution ./temp MyFileWithMultipleLines

When I keep charArray as const, I get warning while memcpy -> ‘memcpy’ discards ‘const’ qualifier

When I remove the const from charArray, I get an error while calling the function takeAction.

Nabz C
  • 538
  • 1
  • 9
  • 28
  • Added a compliable snippet. For now, the error handling from out-of-memory doesn't matter, I need to fix the warning. – Nabz C Oct 31 '21 at 06:02
  • https://stackoverflow.com/q/35319842/1566221 – rici Oct 31 '21 at 06:20
  • 1
    If you're modifying the character values, as `memcpy` does, then obviously you shouldn't declare them to be `const`. So your declaration is wrong. But, as you said, removing the `const` causes problems when `takeAction` is called. This is a subtle problem with `const` which can occur when it is applied multiple levels deep. You can either remove the `const` from the argument declaration, or cast the pointer before passing it. – Tom Karzes Oct 31 '21 at 06:21
  • 1
    Casting generally should be avoided as it may conceal errors, and it is unnecessary at this point in the code. Simply use `char *temporary = malloc((read+1) * sizeof *temporary); memcpy(temporary, line, read); charArray[counter] = temporary;`. (When this pointer is later passed to `free`, a cast may be needed, but that may be a lesser hazard.) – Eric Postpischil Oct 31 '21 at 08:10
  • "Correct way to dynamically allocate a const char array" --> `malloc()` and friends do not return a pointer to `const` data, so the _allocate a const char array_ is not possible. – chux - Reinstate Monica Oct 31 '21 at 14:29
  • "I need to keep the array const and also pass it as a const pointer." --> Hmmm, the array can be kept constant without `const`. A pointer to non-`const` `char` may be passed to `const char *`. "pass it as a const pointer" is mixing `const` array with `const` pointer. I suspect OP wants a pointer to `const` data, not a `const` pointer. – chux - Reinstate Monica Oct 31 '21 at 14:32
  • Post definition of `takeAction()`. – chux - Reinstate Monica Oct 31 '21 at 14:33
  • @chux-ReinstateMonica, Yes, I want a pointer to const data – Nabz C Oct 31 '21 at 19:31
  • @NabaChinde Curious, **why** do you want `const char *` and not a `char *`? What code obliges a `const char *`? – chux - Reinstate Monica Oct 31 '21 at 20:31

1 Answers1

2

You can't have charArray as const as you are writing to it.

Try something like that:

#include<stdlib.h>
#include<stdio.h>
#include<string.h>

void takeAction(const char **charArray) {

    for (int i = 0; i<2; i++) {
        printf("%s\n", charArray[i]);
    }

}

int main(int ac, char **av)
{

    // Read patterns from file

    FILE *fp;
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    int counter = 0;

    char *charArray[1000];

    fp = fopen(av[1], "r");
    if (fp == NULL) {
        fprintf(stderr, "%s File could not be opened \n", av[2]);
        return 1;
    }
    while ((read = getline(&line, &len, fp)) != -1)
    {

        charArray[counter] = malloc(sizeof(char)*(read+1));
        memcpy(charArray[counter], line, read);
        counter++;

        if (counter == 2) {
          counter = 0;
          takeAction((const char **)&charArray[0]);
        }

    }
    fclose(fp);
    return 0;
}
Alaa Mahran
  • 663
  • 4
  • 12