0

I'm reading an input string from the user with scanf().

I want to check if this string is NULL (\0) or not.

Here is my code:

#include<stdio.h>

char *argument; // argument for mycat
scanf("%s", &argument);

if(fork()==0)       // at child
{
    printf("Child process: about to execute \"mycat %s\"\n", &argument);
    fflush(stdout);
    if(strcmp(argument, "") == 0) // <-- Here is the problem
    {

        execlp("mycat", "mycat", &argument, NULL);      // execute child process
    }
    execlp("mycat","mycat", NULL);
}

I'm compiling with g++ compiler on Red Hat 6.1

Edit: The problem is that I'm not able to dereference argument either for the if statement or even for use with strlen().

Mahozi
  • 353
  • 1
  • 2
  • 10
  • 2
    why not use strlen instead, if the length is zero then it would work right? – osirisgothra Mar 02 '14 at 11:16
  • without entering text if you press ENTER it will not return the null.. it return the empty string mean length is zero.. so i will also suggest you to check if **strlen** is 0 mean user didn't enter any value. – Deepak Sharma Mar 02 '14 at 11:19
  • `char *argument;` argument is uninitialised; it does not point to anything. – wildplasser Mar 02 '14 at 11:35
  • Alright, apparently my question is written in a wrong way. I was thinking that when the user inputs `"\0"` it will be equivalent to a null string, however `strlen()` returns a length of 2. So I finally used `strcmp(input, "\\0")` to check if user input is equal to `"\0"` and it worked. I'm accepting the first answer because it's more relevant to the question and it's the first one. I apologize for the confusion! – Mahozi Mar 02 '14 at 17:47

2 Answers2

4

NULL and \0 are not the same thing, though they both evaluate to zero. NULL is a pointer zero, i.e. it's what we use for a null pointer. \0 is the character with ASCII number zero, otherwise known as NUL (one 'L'), i.e. is a char with value 0.

There is an important difference between a char * being NULL (i.e. there not being a string in memory at all), or the string being empty (i.e. only containing one char which is \0 otherwise known as NUL).

To test for the first:

if (!string)

or if you like to be more verbose:

if (string == NULL)

To test for the second:

if (!string[0])

or if you like to be more verbose:

if (string[0] == 0)

Obviously if you need to test for both, test for the first then the second, as the second would dereference a null pointer if string was NULL.

abligh
  • 24,573
  • 4
  • 47
  • 84
  • Thanks for clarifying the difference, the second situation is what I want. However, this solution generates a run-time error and the program never enters the 'if' statement. – Mahozi Mar 02 '14 at 14:46
  • @Ameen There are other things wrong with your program, primarily that you have not allocated any memory for your string. Try `char argument[1024];`. – abligh Mar 02 '14 at 16:21
0

To answer the question:

Check scanf()'s return value to test whether the operation succeeded, read in something.

For your example it would return 0 if nothing was read, or EOF if there was nothing to read from or an error occured.


However there are issues with the example code:

1st issue:

char *argument; // argument for mycat

is just a pointer pointing to "somewhere/nowhere". Reading an uninitalised variable invokes undefined behaviour, copying data to "nowhere" also invokes undefined behaviour.

To fix this allocate some memory to it by for example doing:

char * argument = malloc(42); /* Allocate 41+1 bytes, that is room for a C-"string" 
                                 being 41 characters long. */
strcpy(argument, ""); /* Initalise it to an emtpy string. */

2nd issue:

scanf("%s", &argument);

tries to scan data to the address of argument not where it is pointing to (if it were).

To fix this do

scanf("%s", argument);

or even better, also tell scanf() the size if the buffer to read into, so it won't overflow it. SO assuming the above initialisation, this would be:

scanf("%41s", argument); /* Read one less then there is room, as the 42nd char is used to hold the '0'-terminator. */
alk
  • 69,737
  • 10
  • 105
  • 255
  • `char * argument = malloc(42);` gives me a compilation error: `Invalid conversion from void* to char*`. – Mahozi Mar 02 '14 at 14:40
  • @Ameen: This error indicates you are actually not using a C compiler, but a C++ compiler. – alk Mar 02 '14 at 14:44
  • @Ameen you tagged this "C" where casting the return from `malloc` is harmless but frowned upon. In C++ you need to cast the returned value of malloc; I am told the preferred way in C++ to do that is to use `static_cast<>`, per http://stackoverflow.com/questions/103512/in-c-why-use-static-castintx-instead-of-intx – abligh Mar 02 '14 at 16:20
  • alk&@abligh You're right, I was compiling this with g++, it worked fine with gcc thou. I used `strcmp()` to check user input. – Mahozi Mar 02 '14 at 17:40