I have the following code that takes arguments from the command line and finds the needle in the haystack.
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
int i, j, flag = 0;
for (i = 1; i < argc; i++)
{
char needle[4] = "done";
int length = strlen(argv[i]);
for (j = length - 1; j >= 0; j--)
{
// here is some simple code to print out the string
// in reverse order that I commented out.
argv[i][j] = tolower(argv[i][j]);
}
char *pch = strstr(argv[i], needle);
if (pch)
{
printf("DONE!");
}
//printf("%s", pch);
}
return 0;
}
Now when I try to enter the following arguments:
hi there done
I get:
DONE!
But if I try this:
done
I get no output.
The problem is there if there are multiple arguments, it just ignores the occurrence of "done" in the first argument, or it simply just doesn't find it. While on the other hand, if "done" occurs in any form in the later arguments, it finds it. Why is this happening?
You have undefined behavior here because of calling strstr
with non-nul terminated char array.
You have initialized needle
like this -
char needle[4] = "done";
strstr
expects NUL terminated char
array. Here strstr
won't get the idea of where to stop comparing - you have to make room for the \0
character.
char needle[5] = "done";
or simply
char needle[] = "done";
Know that there is nothing wrong with
char needle[4] = "done";
Even if it is not storing the \0
it is not violating any rules. The array is initialzied with d
,o
,n
,e
. But you passed it to a function which has different expectation - that's where the problem lies. Most of the functions in standard library which handles string expects NUL terminated char
array.
From standard §6.7.9
An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.