-4

I have a problem while checking if a specific character in my string is NULL ('\0'). It gives me false positives, or I think so.

In my code I want to know if somebody inputted more than 3 or less than 2 characters.

I have tried putting NULL instead of '\0' and it still does give me false positives.

This is what I did to check:

int main()
{
    char* str = (char*) calloc(10,sizeof(char));
    scanf("%s",str);
    if (str[1]=='\0' || str[3]!='\0')
        printf("Test");
}

It gives the right output ("Test") when my input is more than 3 characters or less than 2 characters, but does also give me false output of ("Test") when it is 2 characters. It only works as expected when it is exactly 3 characters. I want to make it work (not output "Test") with 2 or 3 characters.

phuclv
  • 37,963
  • 15
  • 156
  • 475
Anthony
  • 69
  • 9
  • You need to ignore everything after the *first* null byte. For instance, if `str[2]` is `'\0'`, then you should not look at `str[3]`, since it shouldn't matter what it contains. But you should just call `strlen(str)` and then check the length directly rather than probing around for null bytes. – Tom Karzes May 18 '19 at 07:55
  • 3
    What makes you think `NULL` is somehow related to `'\0'`? – Swordfish May 18 '19 at 07:57
  • Tom Karzes it gives me this: warning: format '%p' expects argument of type 'void *', but argument 3 has type 'int' [-Wformat=]| warning: format '%p' expects argument of type 'void *', but argument 5 has type 'int' [-Wformat=]| – Anthony May 18 '19 at 07:57
  • `'\0'` is called the `NUL` character. `NULL` is something different, namely the null-pointer constant. – alk May 18 '19 at 07:58
  • So what should I do? I want to check if my string is shorter than 2 or longer than 3 but strlen(str) gives me errors. what shall I do? – Anthony May 18 '19 at 08:00
  • 2
    "*`~~~ warning: format '%p' expects argument of type 'void *' ...`*" there is no line in the code you show which might cause this warning. – alk May 18 '19 at 08:00
  • My code is essentially 250 lines long but the part I mess with is just that. I originally use a struct called "giris" and it has an element that is char* type and named "harf". There is really nothing else to it. – Anthony May 18 '19 at 08:05
  • Why are you discussing code in comments that you have not presented - what are we supposed to do with that. It seems that you should post that in a different question. If `strlen()` is giving you errors, then you are doing something wrong - perhaps you should ask about that rather than asking an X-Y question and asking about your broken solution to the original problem. – Clifford May 18 '19 at 08:43
  • 1
    @alk Actually, `'\0'` is called the null character, or null byte. `NUL` is a character code abbreviation that is sometimes used to represent the null character in some character sets. And of course, NULL is the null pointer, which is completely unrelated to the null character. – Tom Karzes May 18 '19 at 09:05
  • 1
    The code shown in the question, once `` and `` are included, does print “Test” if the input is shorter than two or longer than three characters. It does not give incorrect output of “Test” when the input is two characters. The question is wrong in that statement and fails to show the actual failing code. – Eric Postpischil May 18 '19 at 10:33

1 Answers1

2

By doing if (str[1]=='\0' || str[3]!='\0') you're essentially checking if the input is exactly 1 character long, or not 3 characters long. Any other inputs that are not 3-character long will pass. Your code works, however it's less readable and less efficient. The issue is somewhere else in your code that you didn't show. However to ensure the input is exactly 2 or 3 characters long why don't just check the termination at index 2 or 3?

if ((str[0] && str[1]) &&
    (str[2] == '\0' || str[3] == '\0')) // 2 or 3 letters long
   printf("OK");
else
   printf("Not OK");

or simply use strlen

size_t length = strlen(str);
if (length == 2 || length == 3) printf("OK");

BTW don't allocate memory on heap unnecessarily. For such a tiny array, allocating on stack will be much better. And you don't even need to zero the memory with calloc when you're going to overwrite the string anyway. Even in case you want to initialize the string, just str[0] = 0; will terminate the string and that's enough instead of wasting time zeroing the whole array

And don't cast the result of malloc family in C

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • Thank you! I will try that, but just so you know: strlen gives me errors: warning: format '%p' expects argument of type 'void *', but argument 3 has type 'int' [-Wformat=]| warning: format '%p' expects argument of type 'void *', but argument 5 has type 'int' [-Wformat=]| – Anthony May 18 '19 at 08:03
  • @AnthonyEgeKOPRİ you're using wrong argument to printf. `%p` is for pointers, you're printing an `int`. This is *another* question, but please *Google* first. – Antti Haapala -- Слава Україні May 18 '19 at 08:20
  • 1
    @AnthonyEgeKOPRİ `strlen()` cannot possibly generate a warning about format specifiers - it does not take any format specifiers. You are misreading the diagnostics. – Clifford May 18 '19 at 08:50