0

I'm trying to scan a string/*char into a variable and pass it into a function, but I get the error "format specifies type 'char *' but the argument has type 'const char *'". I need *info to be a const char, but if I change that, I get other errors.

How would I scan in the const char *info correctly into sscanf()?

int main(int argc, char** argv) {
    blk *block;
    char *line;
    const char *info;

    block = block_new();

    printf("insert info");

    while ( (line = readline()) != NULL) {
        sscanf(line, "%s", info);
        insert(block, info);
        free(line);   
    }     
}

insert: insert(blk *block, const char *info)

When I change to char *info instead of const char, I get the error:

warning: variable 'info' is uninitialized when used here
sscanf(line, "%s", info);

note: initialize the variable 'info' to silence this warning
    char *info; = NULL
novel
  • 77
  • 3
  • 10
  • 3
    Apart from removing the `const` qualifier to satisfy the compiler, `line` and `info` are both *uninitialised variables*. They don't point to anything specific. So `sscanf(line, "%s", info);` will not be able to do anything sensible, it is *undefined behaviour*. – Weather Vane Jan 23 '18 at 17:41
  • 1
    *Why* do you "need `*info` to be a const char"? – Weather Vane Jan 23 '18 at 17:46
  • 2
    "*I need `*info` to be a const char*" - no, you need it to be a suitably-long **array** of **non-`const`** char, or a pointer to a suitably-large, dynamically-allocated, **non-`const`** space. Whether dynamically allocated or not, the contents of the space cannot be `const` because you need to modify them (via `sscanf`). – John Bollinger Jan 23 '18 at 17:46
  • @WeatherVane `*info` should be a const char because the function insert() needs a const char parameter – novel Jan 23 '18 at 17:55
  • After the question edit, `info` still needs to point to allocated memory. When `sscanf` derefences the `NULL` pointer it will crash. – Weather Vane Jan 23 '18 at 17:55
  • 2
    It is acceptable to supply a non-const argument to a `const` parameter, but not the other way round. – Weather Vane Jan 23 '18 at 17:59
  • @WeatherVane Okay! How should I allocate memory without knowing how big `info` is? – novel Jan 23 '18 at 18:01
  • 2
    The question is getting too broad - this is not a tutorial service! You could use a fixed length array longer than any input you expect, such as `char info[1000];` and restrict the input with `sscanf(line, "%999s", info);` or you could follow up the many similar questions on SO such as [How can I read an input string of unknown length?](https://stackoverflow.com/questions/16870485/how-can-i-read-an-input-string-of-unknown-length) – Weather Vane Jan 23 '18 at 18:09

1 Answers1

1

You have some problems with your code and with what you want.

A const char* string; declares a pointer to char. You can change the location of where your pointer is pointing, you cannot change the contents of the memory pointed to by the pointer.

const char *string = "Hello";
char line[] = "a b c";

string = "World"; // legal
string[0] = 'w';  // illegal

string = line;    // legal
string[0] = 'A';  // illegal

So using a const char* for reading input with scanf & Co is pointless.

When I change to char *info instead of const char, I get the error:

Did you mean change from char *info to const char? That is even worse, info could hold one character only.

Please don't ignore the compiler warnings and don't silence them. The compiler is telling

warning: variable 'info' is uninitialized when used here


You also are doing

const char *info;
...
sscanf(line, "%s", info);

Let's forget about the const for a moment, let's pretend it's not there. info is an uninitialzed pointer, that means it points to nowhere in particular. Passing it to sscanf yields undefined behaviour, because sscanf is trying to write into a memory location where you may or may not have access to.

How to fix it:

char info[100];
...
sscanf(line, "%s", info);

info is now an array of char that can hold strings with maximal length of 99 characters.

Note that having a const pointer where you want to save input from the user, makes no sense, it cannot be constant by design, because the user input will modify it.

It is perfectly fine to do the other way round: to use a const char* for a non-cost char*, useful when you need to call a function that takes a const char* for an argument:

#include <stdio.h>

void foo(const char *txt)
{
    if(txt == NULL)
        return;

    printf("The text passed is: \"%s\"\n", txt);
}

int main(void)
{
    char line[] = "Hello world";
    foo(line);
    return 0;
}
Pablo
  • 13,271
  • 4
  • 39
  • 59