Home > Enterprise >  How can I output the length of string as I type it?
How can I output the length of string as I type it?

Time:12-07

I am trying to make a small typing racer program where the user will type the words displayed above. I want the program to tell the user their time when the user has met the character limit. I'm able to do this however the user has to press enter after they have finished the sentence. I want to make it so program simultaneously tracks the length of the sentence. I believe that this is something do with thread managing.

Code

var words = "the you that it he she why when is";
TimeOnly timeNow1 = new TimeOnly();
            
while (words2.Length !< numwords)
{
  timeNow1 = TimeOnly.FromDateTime(DateTime.Now);
  Console.WriteLine(words2.Length);
  words2 = Console.ReadLine();
}
var timeNow2 = TimeOnly.FromDateTime(DateTime.Now);
var time = (timeNow2 - timeNow1);
            
Console.WriteLine(time.Seconds);
Console.WriteLine(words2.Length);

CodePudding user response:

You will need to read individual keys with Console.ReadKey instead of whole lines with Console.ReadLine if you don't want to press enter, as a line requires a newline character to be completed. That will in return require you to handle string concatenation manually and deal with cases like the backspace key.

You will also have to do a little bit of manual cursor manipulation if you want to continously output your input (or its length).

I've omitted your time tracking as it did not seem relevant to your question and made a rough example:

string words = "the you that it he she why when is";

int maxChar = words.Length; 
Console.WriteLine(words);
Console.WriteLine($"Max characters: {maxChar}");

string input = "";
while (input.Length! < maxChar)
{
    Console.SetCursorPosition(0, 4);
    var keyInfo = Console.ReadKey();

    //handle backspace and any other char you want to omit from input here
    if (keyInfo.Key == ConsoleKey.Backspace)
        input = input.Substring(0, Math.Max(0, input.Length - 1));
    else
        input  = keyInfo.KeyChar;

    Console.SetCursorPosition(0, 2);
    Console.WriteLine($"You wrote: \"{ input }\"".PadRight(Console.WindowWidth));

    Console.SetCursorPosition(0, 3);
    Console.WriteLine($"Number of chars: {input.Length}".PadRight(Console.WindowWidth));
}
//set cursor below previous output
Console.SetCursorPosition(0, 5);

Console.WriteLine("Press any key to exit");
Console.ReadKey();

PadRight(Console.WindowWidth) prevents previous WriteLine calls with longer strings to mess up your output.

There are definitely some optimizations left to be done to that code but that should get you started.

CodePudding user response:

Your question is "How can I output the length of string as I type it?". Here's a primitive implementation that continuously displays the length of the characters typed in the Title bar, and also uses a Stopwatch to display the current rate in characters per minute..

class Program
{
    static void Main(string[] args)
    {
        var stopwatch = new System.Diagnostics.Stopwatch();
        var words = "the you that it he she why when is";
        var builder = new StringBuilder();
        Console.Title = "Type Racer";
        Console.WriteLine($"Please type:");
        Console.WriteLine(words);
        while(!builder.ToString().Equals(words))
        {
            var keyInfo = Console.ReadKey();
            if(builder.Length.Equals(0))
            {
                stopwatch.Start();
            }
            switch (keyInfo.Key)
            {
                case ConsoleKey.Backspace:
                    builder.Remove(builder.Length - 1, 1);
                    Console.Write(' ');
                    Console.Write('\b');
                    break;
                default:
                    builder.Append(keyInfo.KeyChar);
                    break;
            }
            var seconds = stopwatch.Elapsed.Ticks / (double)TimeSpan.TicksPerSecond;
            var charactersPerSecond = builder.Length / seconds;
            Console.Title = $"{builder.Length} characters in {seconds} seconds = {(charactersPerSecond * 60).ToString("F1")} CPM";
        }
        Console.WriteLine();
        Console.WriteLine("Match!");
        Console.ReadKey();
    }
}

screenshot

  •  Tags:  
  • c#
  • Related