0

I have an array of all some permutations of the word exit in different cases and some of the time it works and some of the time it doesn't. What am I missing?

// Define all possible case permutations of exit
    char *exitStrings[16] = {
        "exit",
        "exiT", 
        "exIt", 
        "eXit",
        "exIT",  
        "eXiT", 
        "eXIt", 
        "eXIT",
        "EXIT", 
        "Exit",
        "EXit",
        "ExIt",
        "ExiT",
        "EXiT", 
        "EXIt", 
        "ExIT"};

    // read the message from client and copy it in buffer
    read(sockfd, buff, sizeof(buff));

    // if read message is one of the permuations of exit strings
    //    exit client
    for (int i = 0; i < sizeof(*exitStrings); i++)
    {
      if (strncmp(buff, exitStrings[i], 4) == 0)
      {
        printf("Client Exit and the Connection is still open\n");
        printf("Listening for new client...\n");
      }
    }

tia

jTruBela
  • 55
  • 7
  • 1
    "doesn't work" is never a good problem description. Please give the exact input, expected result and actual result. Equally importantly please post complete code as a [mre]. – kaylum Apr 30 '22 at 04:18
  • 4
    `sizeof(*exitStrings)` doesn't do what you probably think it does. Should be `sizeof(exitStrings)/sizeof(exitStrings[0])`. Any basic debugging should show you that the loop is not iterating the number of times you expect it to. Run your program in a debugger to trace its execution. – kaylum Apr 30 '22 at 04:19
  • 3
    `sizeof(exitStrings)/sizeof(exitStrings[0])`. You do know you can compare strings without case sensitivity with a library function, right? – Dúthomhas Apr 30 '22 at 04:19
  • 2
    `read` has a return value, you should use it. Use a debugger or print out the data you're receiving and you'll probably see the issue. – Retired Ninja Apr 30 '22 at 04:19
  • @Dúthomhas newbie to the language. Please do tell – jTruBela Apr 30 '22 at 04:21
  • 4
    You might also consider that there are ways to compare strings case insensitively. – Retired Ninja Apr 30 '22 at 04:30
  • 1
    @jTruBela There is no case-insensitive string compare that's part of the C standard library. However, on POSIX systems, you can use `strcasecmp` and `strncasecmp`. On windows, there's `stricmp` and `strnicmp`. – user3386109 Apr 30 '22 at 05:11
  • 1
    If you use [re2c](https://re2c.org/), single-quotes get you a case-insensitive literal. Might be easier; certainly faster. – Neil Apr 30 '22 at 06:21

2 Answers2

2

You can transform the input to lowercase and then compare it to "exit" :

#include <ctype.h>

for(int i = 0; buff[i]; i++)
{
     buff[i] = tolower(buff[i]);
}

if (strncmp(buff, "exit", 5) == 0)
{
    printf("Client Exit and the Connection is still open\n");
    printf("Listening for new client...\n");
 }
Hamza NABIL
  • 146
  • 7
  • You could streamline the process, `strlen(buff) == 4 && (*(uint32_t *)buff & ~538976288u) == 1414092869`, but it might be [1163413844](https://stackoverflow.com/q/12791864/2472827). – Neil Apr 30 '22 at 07:09
  • Sorry , I do not get it ! Can you explain more please ? – Hamza NABIL Apr 30 '22 at 07:14
  • 0x20 is the difference between upper-case and lower-case in ASCII; this masks off ~0x20202020 and tests if it's `EXIT`, converted to `uint32_t`; it depends on the byte-order of your machine, so you would have to write both to be compatible. I think your way is probably better, and doesn't rely on ASCII. +1 – Neil Apr 30 '22 at 07:21
0

seems my original code did not have 1 of the 16 cases I originally counted and I figured out how to compare without case sensitivity. Thanks for all of your help

#include <ctype.h>

// read the message from client and copy it in buffer
    read(sockfd, buff, sizeof(buff));

    if(strncasecmp(buff, "exit",4)==0)
    {
      printf("Client Exit and the Connection is still open\n");
      printf("Listening for new client...\n");
    }
jTruBela
  • 55
  • 7