-2

So I am making an application and I have to use Console.Read because I want at a certain event to rewrite the line, so I can't use Console.ReadLine(). Problem is that my application doesn't output string, instead it outputs multiple lines of numbers. I tried with this line of code. If you need more code sample, comment.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

namespace einuorg_console
{
    class UDPserver
    {
        private static string DatePattern = "HH:mm:ss";

        public static void Initialize(string IPaddress, int port)
        {
            Boolean done = false;
            Boolean exception_thrown = false;
            Socket sending_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            IPAddress sendto_address = IPAddress.Parse(IPaddress);
            IPEndPoint sending_endpoint = new IPEndPoint(sendto_address, port);

            Console.Write("[" + DateTime.Now.ToString(DatePattern) + "]  ");
            Console.WriteLine("einuorg.UDPserver Initialized on address " + IPaddress + ":" + port.ToString());
            while (!done)
            {
                Console.Write("[********]");

                string text_to_send = Console.Read().ToString();

                if (text_to_send.Length == 0)
                {
                    done = true;
                }
                else
                {
                    byte[] sendbuffer = Encoding.ASCII.GetBytes(text_to_send);
                    try
                    {
                        sending_socket.SendTo(sendbuffer, sending_endpoint);
                    }

                    catch (Exception send_exception)
                    {
                        exception_thrown = true;
                        Console.WriteLine(" Exception {0}", send_exception.Message);
                    }

                    if (exception_thrown == false)
                    {
                        Console.WriteLine("\r");
                        Console.Write("[" + DateTime.Now.ToString(DatePattern) + "]  ");
                        Console.WriteLine(text_to_send);
                    }
                    else
                    {
                        exception_thrown = false;
                        Console.WriteLine("The exception indicates the message was not sent.");
                    }
                }
            }
        }
    }
}

Terminal is similar to Console class, but haves more options, something I built.

TheNeosrb
  • 89
  • 1
  • 2
  • 10
  • 1
    Uh... yeah we're going to need more code. You say the problem is with the output, yet the code here is for taking input. What exactly are you entering? – tnw Jun 25 '14 at 20:17
  • Ohh, I forgot to write the rest of the code. Sorry. Will edit the question now. – TheNeosrb Jun 25 '14 at 20:18
  • We need code that can fully reproduce the issue. I have no idea what the `Terminal` class is. Give us code that I can copy-paste into VS and test myself. – gunr2171 Jun 25 '14 at 20:22
  • Okay, so I hate to be a broken record here... but you say the problem is with the output and that `Terminal` is a class you wrote. `Terminal` is doing the output... and you're not showing us what `Terminal.WriteLine` does. Also, I'm still wondering what you're actually entering when you `Console.Read`. You realize that the two parts to get this question answered are 1. What you're inputting, and 2. *How* it's being output. You're not giving us either of those. Not sure how you expect us to answer. – tnw Jun 25 '14 at 20:22
  • Terminal.WriteLine() is same as Console.WriteLine(). I will post full code. – TheNeosrb Jun 25 '14 at 20:24
  • The .NET `Console` interface is a pretty primitive input device. You can make the Windows console do what you want, but you'll have to call the API directly. See [Consoles](http://msdn.microsoft.com/en-us/library/windows/desktop/ms682010(v=vs.85).aspx). You might also be interested in some console code I wrote a while back: http://mischel.com/pubs/consoledotnet.zip – Jim Mischel Jun 25 '14 at 20:40

1 Answers1

1

Console.Read returns an Int32: "[t]he next character from the input stream, or negative one (-1) if there are currently no more characters to be read." You're just calling ToString on that value when you write, so you'll see nothing but numbers. You'd need to check whether the return is -1, and cast to a char if not.

There's also a Console.ReadKey method that gives you an object containing a KeyChar property. It might be easier to work with.

Based on your comments, you might get by with something like:

    public static string ReadLine()
    {
        bool done = false;
        StringBuilder sb = new StringBuilder();
        while (!done)
        {
            ConsoleKeyInfo key = Console.ReadKey(true);
            switch(key.Key)
            {
                case ConsoleKey.Enter:
                    done = true;
                    break;
                case ConsoleKey.Backspace:
                    sb.Length -= 1;
                    Console.Write(key.KeyChar);
                    Console.Write(" ");
                    Console.Write(key.KeyChar);
                    break;
                default:
                    sb.Append(key.KeyChar);
                    Console.Write(key.KeyChar);
                    break;
            }
        }
        }
        return sb.ToString();
    }

That function could probably be cleaned up a bit. It probably won't work for arrow keys. It would replace your Console.Read line as:

string text_to_send = ReadLine();

That would leave you on the current line after the user input because the Enter key is never echoed to the Console. After that, you can carry out your overwrite logic and move to the next line at your leisure.

As an alternative, you could use Console.ReadLine, and adjust the cursor back up one line afterward:

    public static string ReadLine2()
    {
        string input = Console.ReadLine();
        Console.CursorTop -= 1;
        return input;
    }
pmcoltrane
  • 3,052
  • 1
  • 24
  • 30
  • Or `Console.ReadLine()` – gunr2171 Jun 25 '14 at 20:28
  • @gunr2171 OP: `I want at a certain event to rewrite the line, so I can't use Console.ReadLine().` though that could be an invalid requirement to begin with – tnw Jun 25 '14 at 20:29
  • How to make a char array from Console.Read() and convert it to string. That's what I need. – TheNeosrb Jun 25 '14 at 20:29
  • StringBuilder.Append might be of interest to you, then. http://msdn.microsoft.com/en-us/library/yet24s7b%28v=vs.110%29.aspx – pmcoltrane Jun 25 '14 at 20:30
  • 1
    @TheNeosrb Are you *sure* you cant just use `ReadLine`? That sounds like exactly what that function does. – tnw Jun 25 '14 at 20:30
  • Did you try the code? The line where I type the input needs to change, that's why I use the "\r", and write the [date] instead of [****]. That's the whole point of using `Read` instead of `ReadLine` – TheNeosrb Jun 25 '14 at 20:32
  • @TheNeosrb I understand you need `text_to_send` to change at each iteration of the loop. I don't see how `ReadLine` wouldn't do that. – tnw Jun 25 '14 at 20:43
  • When you type the input and press return, you go to next line and then the rewrite happens on that next line, not on the line where you typed the input. That's the problem with `ReadLine` – TheNeosrb Jun 25 '14 at 20:46
  • @TheNeosrb I think your intent is to overwrite the "[********]" with a timestamp later on. So you want a function that will read a line of text from the console when the user hits , but not move to the next line? – pmcoltrane Jun 25 '14 at 20:47
  • Move to the next line after the overwrite. – TheNeosrb Jun 25 '14 at 20:48
  • I've updated my answer based on your comments. You might also be able to use Console.ReadLine, then immediately move the cursor back up a line with Console.SetCursorPosition. – pmcoltrane Jun 25 '14 at 20:57
  • @pmcoltrane Ohh, one more thing. Can you get this ReadLine you made to work with backspace? – TheNeosrb Jun 25 '14 at 21:01
  • That gets trickier: you'll probably also see odd behavior with arrow keys and such. You should be able to create a case for ConsoleKey.Backspace that echoes a backspace, space, and another backspace to the console, and sets sb.Length -= 1. – pmcoltrane Jun 25 '14 at 21:06
  • Yeah, I see, but I have no idea how to achieve that and I need backspace – TheNeosrb Jun 25 '14 at 21:08
  • I've updated, but there might be a lot of exceptional cases to cover (arrow keys, for example), so I added another function that uses Console.ReadLine() and bumps the cursor back up a line afterward. – pmcoltrane Jun 25 '14 at 21:15
  • Yeah, cursor is doing it just fine. Thanks. :) – TheNeosrb Jun 25 '14 at 21:16