1

I'm trying to input a word in the form of a char * in C

Such as :

char *inputText;
scanf("%s",inputText);
printf("This is your string %s",inputText);

I have tried with using

scanf("%s",&inputText);

As well Each time I either get a compile error or Segmentation fault when I run it

"format '%s' expects type 'char *' but argument 2 has type 'char **'

I'm not sure if I'm missing something really simple but It's quite confusing. My code depends on using char * If theres a way to convert an easier input method into char * then can you show me that method?

sun
  • 305
  • 4
  • 13
  • 2
    You can't scan into empty space. Allocate some space for the `inputText` or use a preallocated array. – MicroVirus Nov 26 '15 at 19:02
  • 1
    When scanning a string, you don't need to pass the address of a `char *`... just the `char *` itself. You also need to make sure the pointer points at something (`malloc` space, or use an array, etc.). Also, you should always specify the width so `scanf` won't try to read a string longer than you have space for. – Dmitri Nov 26 '15 at 19:07
  • @zenith I like this question better, as it's way more to the point. That linked one is "OMGHORRIBLEBLOCKOFCODE". – MicroVirus Nov 26 '15 at 19:07
  • @MicroVirus True, there are probably better duplicates out there. – Emil Laine Nov 26 '15 at 19:07
  • [Please don't use `scanf`](http://www.c-faq.com/stdio/scanfprobs.html). – jamesdlin Nov 26 '15 at 19:12
  • @jamesdlin That page's recommendation is to first scan an entire line and then use `sscanf`, which is no different than `scanf`. – MicroVirus Nov 26 '15 at 19:15
  • @MicroVirus Recovering from invalid input, and in general having logical line-oriented input, is far easier if you read a whole line at a time and then try to parse it. – hyde Nov 26 '15 at 20:07
  • @MicroVirus It's no different for `scanf` for *this particular problem*. That doesn't mean that `scanf` is advisable to use in general. – jamesdlin Nov 26 '15 at 22:05

2 Answers2

4

You haven't initialized inputText so it's pointing to some random memory which you probably don't even own. Asking scanf write to that memory location results in undefined behavior.

You need to allocate memory for the pointer to point to:

char *inputText = malloc(amount_of_bytes_to_allocate);

Now inputText points to the allocated memory, and scanf can happily write to that memory location without a segfault. Remember that you must free(inputText) when you're done using the allocated memory.

But preferably, you wouldn't use dynamic memory (malloc) in this case since you can do just fine with automatic memory: just declare inputText as an array instead of a pointer:

char inputText[size_of_array];

Remember that your size_of_array (or amount_of_bytes_to_allocate) must be large enough to hold the entire string that scanf is going to write into the array, including the terminating null character. Otherwise you'll have undefined behavior again.

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
0

First, as a general precaution, it's a good idea to initialize new pointers to NULL so as to ensure they aren't pointing to memory that your program isn't allowed to access.

I would use getline() as an alternative to scanf() especially if the size of your input can vary. It allocates a properly-sized buffer for you, so you don't need to worry about entering too many characters.

char *inputText = NULL;
int inputSize;

if (getline(&inputText, &inputSize, stdin) >= 0)
   printf("This is your string: %s\n", inputText);
else
   printf("Error\n");

You still need to free the memory allocated to inputText yourself, so don't forget to do that and set it to NULL once you're done with it.

  • Just wanted to know; how does &inputSize work in that case? Does it just allocate memory for the char * after it checks the size of the input or does it have some extremely hard to reach limit? – sun Nov 26 '15 at 21:30
  • That parameter is a pointer to an `int` which is used to store the size of the string read by the function. So it basically just counts the number of characters and updates `inputSize` to that number. – MacKenzie Gallant Nov 27 '15 at 15:13