【问题标题】:c# dictionary and forloop/writing to text messing up - how to make it go through once and not through every iterationc# 字典和forloop/写入文本搞砸了 - 如何让它通过一次而不是通过每次迭代
【发布时间】:2011-09-29 00:55:46
【问题描述】:
    using System;
using System.IO;
using System.Collections.Generic;
using System.Threading;
using System.Diagnostics;

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;
                    }

                }

            }
        }
    }
}

代码似乎是遍历每个部分而不是一次。

假设我在控制台中输入 1 2 3,它会在文本文件中写入

富 富吧 富吧巴兹 而不是一开始就写 foo + bar + baz。

我调试了它,它显示它一直在运行,我该如何解决这个问题并让它正确运行?

谢谢!

【问题讨论】:

  • 如果不进行重大更改就无法运行它,很难判断发生了什么。请把它转换成一个简短但完整的程序,我们可以编译和运行。
  • @Jon Skeet - 使用完整代码对其进行了编辑。抱歉,如果它真的很混乱,错误和错误的流程等,我才一个半星期前开始。

标签: c# loops dictionary foreach


【解决方案1】:

这段代码很糟糕,我建议基本上重写它,直到它更短更简单。但是,如果我必须做出最小的改变来让它打印出正确的东西,我会改变这个:

WriteToTextFile(result.Substring(3) + Environment.NewLine);
WriteToCurrentTrip(result.Substring(3) + Environment.NewLine);

到这里:

WriteToTextFile(tdItems[itemNumber] + Environment.NewLine);
WriteToCurrentTrip(tdItems[itemNumber] + Environment.NewLine);

编辑:作为参考,这大致是我如何写你表示你希望你的List 函数做的事情,与 cmets 交错。你可以让它变得更好,但这应该向你展示一些有用的东西。我希望我的预期行为正确。

// 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

如果您将代码正在执行的操作分解为小的、可检查的块,则更容易理解、验证和调试。在我的版本中,您可以看到它获得了正确的航点;然后您可以看到描述看起来正确;然后你可以看到它写入了文件。在你的情况下,它有点试图同时做所有事情,所以更难处理。

【讨论】:

  • 天哪,我才开始使用 C# 大概是一个半星期前。不知道它会“非常”糟糕 - 修改后的代码每行都打印出来。我想要这样,如果一个人输入 1 2 3,它会是 foo + bar + baz,如果他们输入 1 2,它会是 foo + bar。目前,如果我执行 1 2 3 ,它将是第一行:foo,第二行:foo bar 和第三行:foo bar baz。我会用它来更新第一个代码。对不起,如果它真的是乱七八糟的代码,我做错了!
  • 关键是要努力让你的每一段代码都代表过程中的一个自然概念。我将举例说明我将如何改进它。
  • 啊,对了,感谢您这样做并帮助我!我发现很难理解某些事情并记住如何实际编码它以及过程/结构以及事情应该去哪里。每个人都说他们经历过同样的事情,但我只是担心只有我一个人! :(
  • 好的,我加载了它,出于某种原因,每次我在完成“您的旅行已开始”后输入一个数字时,它一直在崩溃,说该文本文件已被另一个进程使用。我检查了我的任务管理器,并且没有其他任何可以使用它的运行。可能是代码?还是纯粹是我的结局?
  • 这可能是因为你的一个旧的仍在后台运行!我会检查任务管理器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多