Using Console.Read() to determine end of file C# - c#

A few days ago I've asked a question concerning how to detect an end of input file of N(N is unknown) lines.
StringBuilder input = new StringBuilder();
int endOfFile = 0
while ((endOfFile = Console.Read()) != -1) {
input.Append(((char)endOfFile).ToString());
input.Append(Console.ReadLine());
}
I've edited my question, but I guess this is the same as some of the hints below.

#Jagannath basically had it, exactly as you asked, except for one little detail: That method works on the console as well, without involving an explicit StreamReader:
string line;
while ((line = Console.ReadLine()) != null)
{
// TODO: Add processing
Console.WriteLine(line);
}
If you're typing directly in the console instead of relying on input redirected from a file, press CTRL-Z or F6 to trigger an "end of file" on the console input. Inside the console, F6 is just a synonym of CTRL-Z.
Be aware that CTRL-Z here is an interrupt sequence or signal, not an input character. It will show ^Z on the screen. but you will not receive the CTRL-Z (U+001A) character in the program. The CTRL-Z sequence is trapped by the console and causes the input stream to close as if the "file had reached the end". Do not insert a CTRL-Z in the input file.
The origin of using CTRL-Z for this purpose goes back to at least the CP/M operating system (a short entertaining story on its own right, but one which is out of scope).

This could help in looping through the file and check for end of file.
using (StreamReader sr = new StreamReader(#"test.txt"))
{
string line;
while ( (line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
UPDATE
Here is a link from msdn ReadLine method

Are you planning on using the shell to redirect standard input to your input file?
Why not use something like TextReader.Read() or TextReader.ReadLine()? http://msdn.microsoft.com/en-us/library/system.io.textreader.aspx

Not quite sure why you're asking this, since the answer you accepted to your previous question is the easiest way to do what you were asking there. Are you just looking for alternate solutions?
You should check the documentation for Console.ReadKey. In the Remarks it says:
The ReadKey method reads from the keyboard even if the standard input is redirected to a file with the SetIn method.
ReadKey will block until you press a key on the keyboard. You can't use ReadKey to detect the end of redirected input.

To read input from a file you can use
var text = File.ReadAllLines("path/to/file.txt");
If what you want is to get input from the console character by character, you can do something like this:
ConsoleKeyInfo keyInfo;
while ((keyInfo = Console.ReadKey()).Key != ConsoleKey.Escape)
{
}
You can replace ConsoleKey.Escape with any other key, or check for key combinations like CTRL+D, CTRL+C, by using keyInfo.Modifiers.

Related

Console.ReadLine() without pressing Enter

When i use:
string fileName = Console.ReadLine();
The user has to drop the item and then press Enter.
I want the user of my Console Application to be able to drag and drop a file into the Console Application Window and take the name of that file without him having to press Enter every time he drops the item as he has to drop a bunch of items.
The files extensions are .xlsx and .py. Is there a way of telling ReadLine to stop reading when it encounters these substrings?
Loop with Console.ReadKey(), extract the returned characters.
var filename = "";
do
{
filename+= Console.ReadKey().KeyChar;
} while (!(filename.StartsWith("\"") && filename.EndsWith(".xlsx\""))
&& filename.EndsWith(".xlsx")); //continue with other extension
Notice the closing double quote, since you'll get quotes enclosing the filename if there's any space. This will break if there's .xlsx in the middle of the file name.
The only way I know to do this, is by dragging files on the .exe file of your program, then reading their names from args[] (passed to main) and load them like you would with any file in C#.
Other way is by having a GUI, in that case you can add DragEventHandler objects to handle drag & drop events. (and data, too).
As i know there is no really good solution for that case except making your own GUI. C# console cannot receive events from file drop, because csrss.exe owns that window not your app.
Next solution will not work in many cases, but if that just feature for testing not production i think that's enough.
static void Main(string[] args)
{
StringBuilder fileNameBuilder = new StringBuilder();
ConsoleKeyInfo cki = new ConsoleKeyInfo();
do
{
while (Console.KeyAvailable == false)
Thread.Sleep(250);
cki = Console.ReadKey(true);
fileNameBuilder.Append(cki.KeyChar);
} while (!fileNameBuilder.ToString().EndsWith(".xlsx") || !fileNameBuilder.ToString().EndsWith(".py"));
var fileName = fileNameBuilder.ToString();
}

How to check if entered data in a TextBox is matching a list of words from notepad

I am doing a project on my own. I want to check if the entered text in a TextBox control matches a list of words entered in notepad.
My questions are:
How to attach notepad to my project?
How to check the words against the list of the words found in notepad?
Please guide me in the right direction.
//This code first read the words in text file one by one,
//which are save in notepad file like one word per line
int aCounter = 0; string aWordInTextFile;
// Read the file and display it line by line.
System.IO.StreamReader file = new System.IO.StreamReader("c:\notePadFile.txt");
while((aWordInTextFile = file.ReadLine()) != null){
Console.WriteLine (aWordInTextFile);
if(textbox.text == aWordInTextFile){
messagebox.show("String Match, found a string in notepad file");
}
aCounter++;
}
file.Close();
// Suspend the screen.
Console.ReadLine();
You dont need to attach your notepad to project, just open it using System.Io classes and read it all and check your string using comparison methods.

How to save what is typed in console to a text file?

Is it possible to save what is typed in the console to a text file?
I know how to write and read from a text file, but I would like to know how to save what is typed in console itself to a text file.
So opening a console, typing text in the console itself (the black console screen), pressing Enter (or something else), and saving it to a file.
I haven't found any answers that work so I'm beginning to think it isn't possible.
On a side note; is there another name for that console application window? Or is it actually called console application window?
I haven't found any answers that work so I'm beginning to think it isn't possible.
What were you searching on? Console.ReadLine() returns a string, which is easily appended to a file:
using (var writer = new StreamWriter("ConsoleOutput.txt", append: true))
{
string line = Console.ReadLine();
writer.WriteLine(line);
}
Not all problems are solved on the web exactly as you require; break it up in smaller parts ("get string from console", "write string to file") and you will find the solution specific to your situation.
If this is about reading output from another process, this is a duplicate of How to spawn a process and capture its STDOUT in .NET?.
Use this code to redirect console output to a text file with name consoleOut.txt
FileStream filestream = new FileStream("consoleOut.txt", FileMode.Create);
var streamwriter = new StreamWriter(filestream);
streamwriter.AutoFlush = true;
Console.SetOut(streamwriter);
There are different approaches:
Just use Console.ReadLine() for this in loop until some specific symbol. At the same time adding lines to a file stream.
Another elegant solution to use Console.SetOUt method. Take a look on second example from MSDN. Pretty much what you need.
If it is no external console window, you can use Console.ReadLine() to get the typed string and save it to a file by calling e.g. File.WriteAllText, StreamWriter,...

C# searching for string in large text file. If you search the same file goto line you last read and start search

If I am searching for strings in the same LOG file many times through the day would it be faster to somehow go to the last line read in the file on the previous search and then begin reading line by line? Would there be any significant savings here?
EXAMPLE FILE
process ID logic
11111 Run some silly logic on middle tier servers.
11111 Still running logic
22222 Run some silly logic on middle tier servers from another user.
11111 Oh look the first process is done.
22222 Still running logic on the second process.
There are times I want many lines of a file from the last time I last loaded it. Currently I use UltraEdit to load the file once and then update file but this still takes quite a bit of time.
In this example above I want ever line from the first process.
NOTE:
The file can be several hundred MB in size at times.
The example above is abbreviated, each process ID may contain 100''s of lines of logic.
I am accessing the log file across a network. I have found that with UE it is faster to load the file from across the network and then continue to update file than to copy to my local PC and then open it.
I am hoping to have a C# console application that can be ran from powershell and pipe the lines I want to the screen or to a file.
Another question I have is what would make this process as efficient as possible?
1. in regards to C# methods used for my file size?
2. in regards to application used to write the utility? I have powershell, C#, C++, perl
This would be possible using Stream.Seek. You would just have to remember what the last position in the stream was, then move forward from there. If your log file only adds lines to it, this will work just fine, and it will certainly be faster than reading and scanning the same lines over and over again.
If you post some of your existing code, I can even help you write the code to do it.
http://msdn.microsoft.com/en-us/library/system.io.stream.seek.aspx
I've wanted to implement something like this myself, so I took some time to give it a shot. Here's an extension method (you'll have to put it in a static class) to FileStream I've come up with:
public static string ReadLineAndCountPosition(this FileStream fs, ref long position)
{
//Check if too great a position was passed in:
if (position > fs.Length)
return null;
bool is_carriage_return = false;
StringBuilder sb = new StringBuilder();
fs.Seek(position, SeekOrigin.Begin);
while (position < fs.Length)
{
var my_byte = fs.ReadByte();
position++;
//Check for newlines
if (is_carriage_return && my_byte == 10)// \n
return sb.ToString();
if (my_byte == 13) // \r
is_carriage_return = true;
else
{
is_carriage_return = false;
sb.Append((char)my_byte);
}
}
return sb.ToString();//We've consumed the entire file.
}
And to use it, you can use ReadLineAndCountPosition by simply calling it and passing in a long parameter which we will save the position in. We will simply .Seek() to this position some time later.
static void Main(string[] args)
{
FileStream fs = new FileStream("testfile.txt",FileMode.Open);
long saved_position = 0;
while(true)
{
string current_line = fs.ReadLineAndCountPosition(ref saved_position);
if (current_line == null || current_line == "SomeSearchString")
break;
}
//Some time later we want to search from the saved position:
while(true)
{
string current_line = fs.ReadLineAndCountPosition(ref saved_position);
if (current_line == null || current_line == "SecondSearchString")
break;
}
}
I ran a few tests myself, and it seems to have worked fine. Let me know if you have any troubles. Hopefully it helps you out.

Execute a line in a text file

I have a program that reads text files filled with code designed to be executed line by line by the program, like a batch file. The problem is that I don't no how to do the line executing part. Here is my code, I thought using the \r would fool the console. But it just shows me a list of lines in the file.
if (tok[0] == "read" && length == 2)
{
try
{
StreamReader tr = new StreamReader(#"C:\Users\Public\"+tok[1]+".txt");
while (!tr.EndOfStream)
{
Console.WriteLine(tr.ReadLine());
}
}
catch
{
Console.WriteLine("No such text file.\n");
}
Prompt();
}
If I knew what to search for to fix my problem in Google, I would have. But I've got no idea.
Thanks
EDIT - My program is a crude synthesizer. It takes inputs in the form of 440 5, or 415 2. The first number is frequency, the second duration. What I'm wanting to do is read text files, which my code does, and execute the sound info line by line, which it doesn't, hence my question. It works perfectly fine from standard input.
Audio synthesis is not straightforward, there used to be
Console.Beep(frequency,duration);
but that's using the PC speaker most systems don't have anymore - here's an example though using DirectSound to achieve something close to what you want.
To read the frequency and duration from your text file you can use something like this (splitting on space):
StreamReader tr = new StreamReader(#"test.txt");
while(!tr.EndOfStream)
{
string[] parts = tr.ReadLine().Split(new[]{' '});
int frequency = Convert.ToInt32(parts[0]);
int duration = Convert.ToInt32(parts[1]);
}
You should load your code and compile it in the runtime.
Check out following examples:
http://www.csharpfriends.com/articles/getarticle.aspx?articleid=118
http://www.codeproject.com/KB/dotnet/evaluator.aspx
EDIT:
You should use Process.Start(cmd); to execute commands in the shell. Here I've found few nice examples: http://dotnetperls.com/process-start
If your program works fine using Standard Input just pass the text file to it like this:
yourprogram.exe < textFile.txt
Then the contents of the text file will be passed to your program on Standard Input.

Categories