Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I know it's silly, but I just want to fix his first version with the minimum possible changes;

  /* Copyright 2023. All unauthorized distribution of this source code
     will be persecuted to the fullest extent of the law*/
  #include <stdio.h>
  #include <stdint.h>
  #include <string.h>
  int main(int argc, char* argv[])
  {
      uint8_t number = argc>1 ? argv[1][strlen(argv[1])-1]-'0' : printf("Usage: odd-or-even number\n");
      if (number == 0)
          printf("even\n");
      if (number == 1)
          printf("odd\n");
      if (number == 2)
          printf("even\n");
      if (number == 3)
          printf("odd\n");
      if (number == 4)
          printf("even\n");
      if (number == 5)
          printf("odd\n");
      if (number == 6)
          printf("even\n");
      if (number == 7)
          printf("odd\n");
      if (number == 8)
          printf("even\n");
      if (number == 9)
          printf("odd\n");
      if (number == 10)
          printf("even\n");
  }
This way it basically works. It's a shame that it doesn't call out a non numeric argument but that's about the only problem. It relies on a trick, printf() returns the number of characters printed, so the error message string needs to be longer than 10.


Wouldn't using elif for all comparisons after the first improve performance?

Or is the performance considered worse because it becomes O(n) (where n < MAX_UINT) vs. constant time ( O(MAX_UINT) )


It certainly would be normal to use else if (or switch) if you wanted to be picky but really such changes are inconsequential here. And I was trying to change just one line. Sadly I also had to quietly change stdlib.h to string.h as well.


If you wanted to avoid <string.h>, you could use the poor man's strlen(), snprintf(0,0,"%s",argv[1]). For full input validation without adding any more statements, the best I can get (in ISO C) is

      uint8_t number = (argc<2||sscanf(*++argv,"%*[0123456789]%n",&argc)||argc--[*argv]?printf("bad\n"):argc[*argv])-'0'; // No problems here
Though with either function you may run into issues if the OS allows arguments longer than INT_MAX. To be defensive, you could use "%32767s" or "%*32767[0123456789]%n" instead, at the cost of failing inputs longer than 32KiB.


Marvellous, love it. Thank you.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: