I am trying to merge two programs, using output of one as an input to other.
Program # 1 ends up writing the output and program 2 wants user input both using console. I don't want result of program 1 to be shown as output but rather used as input so that program 2 doesn't ask for user input.
foreach (var item in result)
{
Console.Write(item);
}
Console.ReadLine();
**end of program 1**
**program 2**
Console.WriteLine("Please, enter numbers");
var numbersStr = Console.ReadLine();
if (!string.IsNullOrEmpty(numbersStr))
{
numbersStr = numbersStr.Trim();
and program continues
It seems like you just need methods. You don't need two programs.
// name this method appropriately!
private static string Program1() {
string retVal = "";
// here goes your program 1
// replace every Console.Write with retVal += ...
// e.g.
foreach (var item in result)
{
retVal += item.ToString();
}
return retVal;
}
// name this properly as well
private static void Program2(string input) {
// program 2 goes here
}
In your Main,
Program2(Program1());
If this is a trivial program you could write the output of the first program to a file or database. And your second program could read from that.
using (var fileWriter = new StreamWriter(pathOfFile))
{
foreach (var item in result)
{
fileWriter.Write(item);
}
}
end of program 1
program 2
Console.WriteLine("Please, enter numbers");
var numbersStr = Console.ReadLine();
var input = File.ReadAllText(pathOfFile)
if (!string.IsNullOrEmpty(input))
{
numbersStr = numbersStr.Trim();
}
Related
I am writing a simple shell program and I have written a few commands for the program. Unfortunately, I also want to allow the shell to pipe an echo command out to a text file and also be able to cat said file and output the contents. The issue I am having is the way that I have written how the echo command works.
public static void Main(string[] args)
{
string command;
do
{
Console.ForegroundColor =
ConsoleColor.DarkGreen;
Console.Write("console > ");
Console.ForegroundColor = ConsoleColor.Gray;
command = Console.ReadLine();
Handle(command);
} while (command != "exit");
}
public static string Handle(string command)
{
if (command.StartsWith("echo "))
{
command = command.Replace("\"", "");
Console.WriteLine(command.Substring(5));
}
if (command.Contains("->"))
{
// logic for echo "text" -> output.txt
}
}
}
You can try something like this that takes the content from before and after the ->. You will have to validate the string of course before you run this
string cmd = #"echo ""text"" -> output.txt";
string text = cmd.Split(" -> ").First().Replace("echo ", "").Replace(#"""", "");
string file = cmd.Split(" -> ").Skip(1).First();
Or, a more general solution (to allow extra commands). First I create a dictionary of commands. The Action<string,string> type represents a delegate to a function that takes two strings as as parameters. The StringComparer.CurrentCultureIgnoreCase means that the case (upper or lower) is ignored when matching:
private static readonly Dictionary<string, Action<string, string>> CommandList =
new Dictionary<string, Action<string, string>>(StringComparer.CurrentCultureIgnoreCase)
{
{"echo", EchoCommand},
{"exit", ExitCommand}
};
Now I have to implement the commands. The echo command is close to what you want to do (I don't bother trying to write to the file, but I get it to the point where you could). The exit command is empty (I just let it fall through). You may want to refactor that behavior.
private static void EchoCommand(string commandText, string file)
{
var fileNote = string.IsNullOrEmpty(file) ? string.Empty : $" ({file})";
Console.WriteLine($"{commandText} {fileNote}");
}
private static void ExitCommand(string commandText, string file)
{
}
Now I need something to parse my command line. This is a brute force hack, but it works. The weird return type is a tuple, an entity that contain many values, in this case three named strings.
static (string command, string text, string file) ParseCommandLine(string commandLine)
{
//find the first space:
var endOfCommandIndex = commandLine.IndexOf(" ");
if (endOfCommandIndex < 0)
{
return (commandLine, string.Empty, null);
}
//otherwise
var command = commandLine.Substring(0, endOfCommandIndex);
var rest = commandLine.Substring(endOfCommandIndex);
var redirectIndex = rest.IndexOf("->");
if (redirectIndex < 0)
{
//use the substring to get rid of the "->"
return (command, rest.Substring(2).Trim(), null);
}
//otherwise (the "+ 2" is to get rid of the "->"
return (command, rest.Substring(0, redirectIndex).Trim(), rest.Substring(redirectIndex + 2).Trim());
}
It bangs away at the command line string and parses it into a Command, some Text and possibly a File to redirect to. I only changed a bit of the core of your Main function. It ends up looking like:
string command, text, file;
do
{
Console.ForegroundColor = ConsoleColor.DarkGreen;
Console.Write("console > ");
Console.ForegroundColor = ConsoleColor.Gray;
var commandLine = Console.ReadLine();
(command, text, file) = ParseCommandLine(commandLine);
if (CommandList.TryGetValue(command, out var commandAction))
{
commandAction(text, file);
}
else
{
Console.WriteLine("ERROR: Unknown Command");
}
} while (command != "exit");
The TryGetValue call on the dictionary will return true if the command text is in the dictionary. If it returns true, then the commandAction will represent the function to call (so it calls it). If it returns false, then the command is not in the dictionary, so an error is signaled to the user.
And finally, you don't need to put the string to echo in quotes. It just echoes whatever it finds.
Write a program which uses two custom methods:
Custom method 1 should take user input and save it to a text file.
Custom method 2 should open the text file containing the user's input data and display it to the screen.
Your program should not crash if the user is not allowed to save files in the directory.
Your program should not crash if it is not able to open the user file.
I currently have
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Enter text to save:");
string textInput = Console.ReadLine();
using (StreamWriter writer = new StreamWriter("Final.txt"))
{
writer.WriteLine(textInput);
}
string line = "";
using (var sr = new StreamReader("Final.txt"))
{
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine("The Saved text is:");
Console.WriteLine(line);
}
}
}
}
I believe that covers the first two options but I have problems recognizing the other two.
I am completely new to coding and so I am at total odds about what I should do. Any tips would be appreciated.
Regards,
First of all, you don't need to use StreamWriter, you can simply write text to a file by using File.WriteAllText which solves the issue that you seemed to experience: the file not being closed properly.
Secondly, in your shown code you are not handling the possible errors that you are supposed to handle:
The user is not allowed to write to or read from the directory specified
The file cannot be opened.
If the user is not allowed to write to the file or read from it, a System.UnauthorizedAccessException is thrown. If the file cannot be opened, a System.IOException is thrown.
So what we want to do is handle those exceptions by surrounding the call to File.WriteAllText with a
try
{
File.WriteAllText(...);
}
catch(UnauthorizedAccessException)
{
...
}
catch(IOException)
{
...
}
and we do the same for File.ReadAllText as well.
Complete code for your task:
private string fileName = "Final.txt";
public void CustomMethod1()
{
Console.WriteLine("Enter the text to save: ");
string textInput = Console.ReadLine();
try
{
File.WriteAllText(this.fileName, textInput);
}
catch (UnauthorizedAccessException)
{
Console.WriteLine($"You are not allowed to save files in the directory '{this.fileName}'.");
}
catch (IOException e)
{
Console.WriteLine($"The error '{e.Message}' occured while saving the file.");
}
}
public void CustomMethod2()
{
if (!File.Exists(this.fileName))
{
Console.WriteLine($"Cannot find the file '{this.fileName}'.");
}
try
{
Console.WriteLine("The saved text is: ");
Console.WriteLine(File.ReadAllText(this.fileName));
}
catch (UnauthorizedAccessException)
{
Console.WriteLine($"You are not allowed to read files from the directory '{this.fileName}'.");
}
catch (IOException e)
{
Console.WriteLine($"The error '{e.Message}' occured while opening the file.");
}
}
public static void Main(string[] args)
{
Program program = new Program();
program.CustomMethod1();
program.CustomMethod2();
}
I have 5 files, which I have parsed. They are text files, and I dont know how to pass them to the program via command line arguemnt. I am using visual studio, and C sharp. When I go into Project>Properties>Debug>Command Line Argument> Do I just type in the files? Like File01.txt,File02.txt etc...
The simplest way is to realise that command line arguments are passed to you as an array of strings in your Main(...) method.
class TestClass
{
static void Main(string[] args)
{
// Display the number of command line arguments:
System.Console.WriteLine(args.Length);
foreach(var arg in args)
{
System.Console.WriteLine(arg);
}
}
}
(Broadly from: https://msdn.microsoft.com/en-us/library/acy3edy3.aspx)
Specifically in answer to your question -- yes, in the debug tab, but they need to be space-separated, not comma separated.
If you actually want to open and read the files, you'll need something like (assuming they're text files):
int counter = 0;
string line;
using(var file = new System.IO.StreamReader(arg))
{
while((line = file.ReadLine()) != null)
{
Console.WriteLine (line);
counter++;
}
}
(Broadly from: https://msdn.microsoft.com/en-GB/library/aa287535%28v=vs.71%29.aspx)
In your Main method, you can process your arguments in the following way:
static void Main(string[] args)
{
if (args.Length > 0)
{
foreach (string p in args)
{
Console.WriteLine(p);
}
}
else
{
Console.WriteLine("Empty input parameters");
}
}
When you run your program from command line, you have to use the following syntax:
C:\>yourprogram.exe firstfile.txt secondfile.xls thridfile.dat
This question already has answers here:
How to add c# login attempts loop in console application?
(3 answers)
Closed 6 years ago.
I need to create a simple C# Sharp program that takes userid and password as input (type string). After 3 wrong attempts user should be rejected.
I have started but I'm not sure how the logic should be properly done.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UserId
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Type username");
String UserId1 = Console.ReadLine();
Console.WriteLine("Type password");
String Pass = Console.ReadLine();
String UserIdCorrect = "test1";
String PassCorrect = "password1";
int MaxAttempts = 3;
Console.ReadKey();
if (UserId1 != UserIdCorrect && Pass != PassCorrect ) {
MaxAttempts++;
}
Console.ReadKey();
}
}
}
First of all, even before writing a single line of code, try to think about naming conventions for a minute or two. This is like "putting foam on your face before having a shave. You can get a shave even without the shaving foam but the experience wouldn't be nice". Try this link for more info [https://msdn.microsoft.com/en-us/library/ms229045(v=vs.110).aspx].
Now moving towards your question, if I have to only fulfill your requirement, this code will be suffice. Here I'm taking "valid" as an identifier for the correct credentials:
<code>
//Login Attempts counter
int loginAttempts = 0;
//Simple iteration upto three times
for (int i = 0; i < 3; i++)
{
Console.WriteLine("Enter username");
string username = Console.ReadLine();
Console.WriteLine("Enter password");
string password = Console.ReadLine();
if (username != "valid" || password != "valid")
loginAttempts++;
else
break;
}
//Display the result
if (loginAttempts > 2)
Console.WriteLine("Login failure");
else
Console.WriteLine("Login successful");
Console.ReadKey();
</code>
Just run the for loop 3 times and if still user enter the wrong entry than just disable the window .
I guess you are a beginner. I've commented the code.
int maxAttempts = 3;
// looping n (maxAttempts) times
for(int i = 0; i < maxAttempts; i++)
{
// get input and check it
}
// do what ever you want here.
// at least show up a message
Many ways. As HebeleHododo commented you could also use a while-loop and check with if-else if your maxAttempts is reached.
There is a function, which can read a single line from the console input (Console.ReadLine()), but I wish to read or some arbitrary number of lines, which is unknown at compile time.
Of course it is. Just use just read a single line (using ReadLine() or whatever else you please) at a time within either a for loop (if you know at the beginning of reading how many lines you need) or within a while loop (if you want to stop reading when you reach EOF or a certain input).
EDIT:
Sure:
while ((line = Console.ReadLine()) != null) {
// Do whatever you want here with line
}
Some of the other answers here loop until a null line is encountered while others expect the user to type something special like "EXIT". Keep in mind that reading from the console could be either a person typing or a redirected input file:
myprog.exe < somefile.txt
In the case of redirected input Console.ReadLine() would return null when it hits the end of the file. In the case of a user running the program interactively they'd have to know to how to enter the end of file character (Ctrl+Z followed by enter or F6 followed by enter). If it is an interactive user you might need to let them know how to signal the end of input.
simple example:
class Program
{
static void Main()
{
CountLinesInFile("test.txt"); // sample input in file format
}
static long CountLinesInFile(string f)
{
long count = 0;
using (StreamReader r = new StreamReader(f))
{
string line;
while ((line = r.ReadLine()) != null)
{
count++;
}
}
return count;
}
}
The best thing to do here is use a loop:
string input;
Console.WriteLine("Input your text (type EXIT to terminate): ");
input = Console.ReadLine();
while (input.ToUpper() != "EXIT")
{
// do something with input
Console.WriteLine("Input your text(type EXIT to terminate): ");
input = Console.ReadLine();
}
Or you could do something like this:
string input;
do
{
Console.WriteLine("Input your text (type EXIT to terminate): ");
input = Console.ReadLine();
if (input.ToUpper() != "EXIT")
{
// do something with the input
}
} while (input.ToUpper() != "EXIT");