-1

I'm trying to read a single character into a char* called val and when I use scanf() it returns null. Here is my code:

#include <stdio.h>

int main(int argc, char *argv[])
{
    char *val;
    if (argc == 2)
    {
        val = argv[1];
    }
    else
    {
        scanf("%s", val);
    }
    printf("Val = %s", val);
}

If I try to use malloc(), it will continuously read from standard input if the input is one character long, which is how long I want my input to be.

  • 5
    `val` is unitialized, and `%s` will not read a single character but a whole line. I think it is time to revisit some beginner material on C input handling. – Emanuel P Feb 24 '23 at 03:10
  • How do I read a single char then? When I use %c that doesn't work either. Plus val has to be a char* because it has to be able to accept an argument. – Reece Cristea Feb 24 '23 at 03:11
  • `%c` or use `getchar()`, but you have to initialize `val` – Emanuel P Feb 24 '23 at 03:13
  • Like I said in my last comment if you read it, %c doesn't work because it needs to be a char* so it can read in an argument sand getchar() doesn't work because once again it needs to be a char*. – Reece Cristea Feb 24 '23 at 03:17
  • 2
    `char val=0; scanf("%c", &val);` – Iłya Bursov Feb 24 '23 at 03:17
  • You must pass a pointer to some storage — you're passing an uninitialized pointer. You can either use `char c; char *val = &c; scanf(" %c", val);` or do without the pointer variable (a more sensible option) and use `char c; scanf(" %c", &c);`. Of course, you should also check the return value from `scanf()`. The space before the `%c` is not accidental either — it skips over white space. Note that your `printf()` statement will change too. A third alternative, continuing to use `%s`, would be `char str[100]; char *val = str; if (scanf("%99s", val) != 1) { …error… }`. (The off-by-one is sad!) – Jonathan Leffler Feb 24 '23 at 03:21
  • [The Definitive C Book Guide and List](https://stackoverflow.com/q/562303/995714) – phuclv Feb 24 '23 at 03:38
  • 1
    A big problem here is that, contrary to the title of the post, you have *no idea* what `scanf` returned, since you're discarding the return value. Don't. `scanf` returns the number of fields it successfully read. *Check it.* If it's less than what you expect, *stop* and handle error. Don't just blindly push on, accessing uninitialized variables and wondering why it doesn't work. – Tom Karzes Feb 24 '23 at 05:23
  • Also, if you're going to store a string through `val` (via `scanf`), then you need to initialize `val` to point to valid storage. In this code, it's uninitialized, so you're storing through an uninitialized pointer. That's about as severe a bug as you can have. Never, ever do that. Maybe spend some time reading a tutorial and thinking about what it's telling you. You should be able to catch obvious bugs like this without assistance. – Tom Karzes Feb 24 '23 at 05:26

1 Answers1

1

Why does scanf("%s", val); return null?

scanf() needs to read input into a valid location.


With scanf("%s", val);, code passes to scanf() an uninitialized pointer val to scanf(). This leads to undefined behavior (UB).

Instead, pass a pointer to memory ready to accept the input.

  • Pass a pointer to a location ready to accept characters.

  • Use a width to avoid overrun.

  • check the return value.

    char *val;
    char s[100+1]; 
    if (argc == 2) {
      val = argv[1];
    } else {
      if (scanf("%100s", s) != 1) {
        fprintf(stderr, "Invalid input\n");
        return -1;
      }
      val = s;
    }

To read a single character use:

char ch; 
if (scanf("%c", &ch) != 1) {
  fprintf(stderr, "Invalid input\n");
  return -1;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256