c# dictionary and forloop/writing to text messing up - how to make it go through once and not through every iteration
using System;
using System.IO;
using System.Collections.Generic;
using System.Threading;
using System.Diagnostics开发者_如何学JAVA;
namespace ConsoleApplication9
{
class main
{
private static StreamWriter objWriter = new StreamWriter(@"D:\text1.txt", true);
private static StreamWriter tripWriter = new StreamWriter(@"D:\text2.txt", true);
private static void Main()
{
WelcomeMenu();
}
public static void WelcomeMenu()
{
Console.WriteLine("Welcome to Pow Drop Log v1");
Console.WriteLine("A. Press A to start the trip");
while (true)
{
string enteredWelcome = Console.ReadLine();
{
if (enteredWelcome == "a")
{
List();
}
else
{
Console.WriteLine("That is an invalid option");
continue;
}
}
}
}
public static void WriteToTextFile(string text)
{
objWriter.Write(text);
objWriter.Flush();
}
public static void WriteToCurrentTrip(string text)
{
tripWriter.Write(text);
tripWriter.Flush();
}
public static void List()
{
Stopwatch Triptime = new Stopwatch();
Triptime.Start();
Console.WriteLine("You have started the trip");
Dictionary<string, string> tdItems = new Dictionary<string, string>();
tdItems.Add("1", "foo");
tdItems.Add("2", "bar");
tdItems.Add("3", "bar");
tdItems.Add("4", "end");
while (true)
{
string[] items = Console.ReadLine().Split(' ');
string result = null;
int result1;
TimeSpan timeSpan = Triptime.Elapsed; string time = string.Format("{0:00}:{1:00}:{2:00}", timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds);
foreach (string itemNumber in items)
{
if (tdItems.ContainsKey(itemNumber) && (int.TryParse(itemNumber, out result1)))
{
result += " + " + tdItems[itemNumber];
WriteToTextFile(tdItems[itemNumber] + Environment.NewLine);
WriteToCurrentTrip(tdItems[itemNumber] + Environment.NewLine);
}
if (!tdItems.ContainsKey(itemNumber) && (int.TryParse(itemNumber, out result1)))
{
Console.WriteLine("You have entered a drop which is not in the database, Try again");
continue;
}
else if (itemNumber == "end")
{
Triptime.Stop();
Console.WriteLine("End of Trip");
Console.WriteLine("Elapsed time " + time);
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("");
WelcomeMenu();
break;
}
}
}
}
}
}
The code seems to be going through each part instead of once.
Say if I typed 1 2 3 in the console, in the text file it would write
foo foo bar foo bar baz instead of it writing foo + bar + baz in the first place.
I debugged it and it shows it keeps going through, how would I be able to fix this and make it so it does it correctly?.
Thanks!
This code is very bad, and I recommend basically rewriting it until it is much shorter and simpler. But if I had to make the smallest change possible to make it print out the right thing, I'd change this:
WriteToTextFile(result.Substring(3) + Environment.NewLine);
WriteToCurrentTrip(result.Substring(3) + Environment.NewLine);
To this:
WriteToTextFile(tdItems[itemNumber] + Environment.NewLine);
WriteToCurrentTrip(tdItems[itemNumber] + Environment.NewLine);
EDIT: For reference, here's roughly how I'd write what you indicated you wanted your List
function to do, with comments interleaved. You could make it nicer yet, but this should show you some useful things. I hope I got the intended behavior right.
// StartNew happens to be a quicker way to create and initialize a Stopwatch
Stopwatch triptime = Stopwatch.StartNew();
Console.WriteLine("You have started the trip");
// you can use collection initializer syntax to make it nicer to read when
// you want to add lots of things to a data structure
var tdItems = new Dictionary<string, string> {
{ "1", "foo" },
{ "2", "bar" },
{ "3", "baz" },
{ "4", "end" },
};
while (true)
{
string[] items = Console.ReadLine().Split(' ');
// you can use format strings to easily customize the stringification
// of DateTime and TimeSpan objects, see the MSDN docs
string time = string.Format("{0:c}", triptime.Elapsed);
List<string> waypoints = new List<string>();
// it's easiest to first find the destinations your trip has to visit
foreach (string itemNumber in items)
{
if (tdItems.ContainsKey(itemNumber))
waypoints.Add(tdItems[itemNumber]);
else
Console.WriteLine(
"You have entered a drop which is not in the database...");
}
// string.Join is an easy way to avoid worrying about putting an extra
// "+" at the front or end
string tripDescription = string.Join(" + ", waypoints);
// "using" is generally important so you don't hold a lock on the file
// forever, and it saves you from manually calling "flush" -- it
// flushes when the writers are disposed at the end of the using block
using (var objWriter = new StreamWriter(@"D:\text1.txt", true))
using (var tripWriter = new StreamWriter(@"D:\text2.txt", true))
{
// WriteLine adds a newline for you
objWriter.WriteLine(tripDescription);
tripWriter.WriteLine(tripDescription);
}
if (waypoints.Contains("end"))
{
Console.WriteLine("End of Trip");
Console.WriteLine("Elapsed time " + time);
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("");
break;
}
}
// you'll get the welcome menu again when you return from this function
If you break up what your code is doing into small, checkable chunks, it's a lot easier to understand, verify, and debug. In my version, you can see that it got the right waypoints; then you can see that the description looks right; then you can see that it wrote to the file. In yours, it's sort of trying to do everything at the same time, so it's harder to work with.
精彩评论