1
\$\begingroup\$

I've written a code snippet that will get a (max.) 14 character string from the user input, and while the user is typing, simultaneously echo it out to the screen.

It seems a bit long and ugly, so I was wondering if any of you would happen to have ideas on how to shorten, and generally optimize this.

for(int i = 0; i < 15; i++)
{
    char npt = _getch(); // Get input

    if(i == 14) // Last character (user has to press \r or \b)
    {
        if(npt == '\r') // enter, break loop
            break;
        else if(npt == '\b') // backspace, re-loop
        {
            if(!name.empty())
                name.erase(std::prev(name.end()));
            if(i >= 1)
                i -= 2;
            else
                i--;
        }
        else // other input, meaning re-loop
            i--;

        SetConsoleCursorPosition(hOut, cDraw);
        printf("              "); // clear string area
        SetConsoleCursorPosition(hOut, cDraw);
        std::cout << name; // echo string
        continue;
    }
    else
    {
        if(npt == '\r')
            break;
        else if(npt == '\b')
        {
            if(!name.empty())
                name.erase(std::prev(name.end()));
            if(i >= 1)
                i -= 2;
            else
                i--;
        }
        else
            name += npt; // add input to string

        SetConsoleCursorPosition(hOut, cDraw);
        printf("              ");
        SetConsoleCursorPosition(hOut, cDraw);
        std::cout << name;
    }
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

c++ isn't really my language, but I believe this would be an identical loop:

for(int i = 0; i < 15; i++)
{
  char npt = _getch(); // Get input

  if(npt == '\r')
    break;
  else if(npt == '\b')
  {
    if(!name.empty())
      name.erase(std::prev(name.end()));
    if(i >= 1)
      i -= 2;
    else
      i--;
  }
  else if(i == 14)
    i--;
  else            
    name += npt; // add input to string

  SetConsoleCursorPosition(hOut, cDraw);
  printf("              ");
  SetConsoleCursorPosition(hOut, cDraw);
  std::cout << name;
}

The only difference between your first if and the else is the final else line, so I moved the conditional to the end to avoid repeating the same logic.

Additionally, I assume there's some way you could pad name with blank spaces so that you only have to call SetConsoleCursorPosition and print once per iteration.

\$\endgroup\$
3
  • \$\begingroup\$ Hey, that's a really good answer! I'll accept it in a minute. Meanwhile, would you have an idea on how to efficiently do the name padding? \$\endgroup\$
    – user32926
    Dec 4, 2013 at 23:11
  • \$\begingroup\$ I don't know. But this page seems to provide a possible method. You might ask on StackOverflow if you're unable to find a way after searching. \$\endgroup\$
    – Daniel
    Dec 5, 2013 at 0:23
  • \$\begingroup\$ Ok, I'll search around for an answer. Thanks, man. \$\endgroup\$
    – user32926
    Dec 5, 2013 at 0:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.