3

试图使用外部文件(txt 或 CSV)在 C# 中创建文件流。文件中的数据是由以下组成的问答游戏的数据:

1 个简短问题 4 个可能的答案 1 个正确答案

该程序应该能够告诉用户他是否正确回答。

我正在寻找有关如何使用外部文件中的数据在 C# 中创建简单测验的示例代码/算法/教程。此外,关于如何构建 txt 文件的任何建议(我如何将答案标记为正确的?)。有什么建议或链接吗?谢谢,

4

4 回答 4

12

如果您必须从文件(而不是从数据库)加载数据,我的建议是使用 XML 文件。

使用文本文件需要您非常清楚地定义问题的各个元素的结构。使用 CSV 可能有效,但您必须定义一种在问题或答案本身中转义逗号的方法。这可能会使事情复杂化。

因此,重申一下,恕我直言,XML 是存储此类数据的最佳方式。这是一个简短的示例,展示了您可能使用的可能结构:

<?xml version="1.0" encoding="utf-8" ?>
<Test>
  <Problem id="1">
    <Question>Which language am I learning right now?</Question>
    <OptionA>VB 7.0</OptionA>
    <OptionB>J2EE</OptionB>
    <OptionC>French</OptionC>
    <OptionD>C#</OptionD>
    <Answer>OptionA</Answer>
  </Problem>
  <Problem id="2">
    <Question>What does XML stand for?</Question>
    <OptionA>eXtremely Muddy Language</OptionA>
    <OptionB>Xylophone, thy Music Lovely</OptionB>
    <OptionC>eXtensible Markup Language</OptionC>
    <OptionD>eXtra Murky Lungs</OptionD>
    <Answer>OptionC</Answer>
  </Problem>
</Test>

就将 XML 加载到内存而言,.NET 提供了许多处理 XML 文件和字符串的内在方法,其中许多完全混淆了必须直接与 FileStreams 交互。例如,该XmlDocument.Load(myFileName.xml)方法将在一行代码中为您内部完成。就个人而言,虽然我更喜欢使用XmlReaderand XPathNavigator

查看System.Xml 命名空间的成员以获取更多信息。

于 2009-02-21T15:05:37.297 回答
5

确实没有固定的方法可以做到这一点,尽管我同意对于一个简单的测验问题数据库,文本文件可能是您的最佳选择(与 XML 或适当的数据库相反,尽管前者不会完全矫枉过正) .

这是一组测验问题的基于文本的格式的一个小示例,以及将问题读入代码的方法。编辑:我试图让它尽可能容易地跟随(使用简单的结构),有很多评论!

文件格式

示例文件内容。

第一个问题的问题文本...
答案 1
答案 2
!答案 3(正确答案)
答案 4

第二个问题的问题文本...
!答案 1(正确答案)
答案 2
答案 3
答案 4

代码

这只是在代码中存储每个问题的简单结构:

struct Question
{
    public string QuestionText; // Actual question text.
    public string[] Choices;    // Array of answers from which user can choose.
    public int Answer;          // Index of correct answer within Choices.
}

然后,您可以使用以下代码从文件中读取问题。除了对象初始化器之外,这里没有什么特别的(基本上这只是允许您在创建对象的同时设置对象的变量/属性)。

// Create new list to store all questions.
var questions = new List<Question>();

// Open file containing quiz questions using StreamReader, which allows you to read text from files easily.
using (var quizFileReader = new System.IO.StreamReader("questions.txt"))
{
    string line;
    Question question;

    // Loop through the lines of the file until there are no more (the ReadLine function return null at this point).
    // Note that the ReadLine called here only reads question texts (first line of a question), while other calls to ReadLine read the choices.
    while ((line = quizFileReader.ReadLine()) != null)
    {
        // Skip this loop if the line is empty.
        if (line.Length == 0)
            continue;

        // Create a new question object.
        // The "object initializer" construct is used here by including { } after the constructor to set variables.
        question = new Question()
        {
            // Set the question text to the line just read.
            QuestionText = line,
            // Set the choices to an array containing the next 4 lines read from the file.
            Choices = new string[]
            { 
                quizFileReader.ReadLine(), 
                quizFileReader.ReadLine(),
                quizFileReader.ReadLine(),
                quizFileReader.ReadLine()
            }
        };

        // Initially set the correct answer to -1, which means that no choice marked as correct has yet been found.
        question.Answer = -1;

        // Check each choice to see if it begins with the '!' char (marked as correct).
        for(int i = 0; i < 4; i++)
        {
            if (question.Choices[i].StartsWith("!"))
            {
                // Current choice is marked as correct. Therefore remove the '!' from the start of the text and store the index of this choice as the correct answer.
                question.Choices[i] = question.Choices[i].Substring(1);
                question.Answer = i;
                break; // Stop looking through the choices.
            }
        }

        // Check if none of the choices was marked as correct. If this is the case, we throw an exception and then stop processing.
        // Note: this is only basic error handling (not very robust) which you may want to later improve.
        if (question.Answer == -1)
        {
            throw new InvalidOperationException(
                "No correct answer was specified for the following question.\r\n\r\n" + question.QuestionText);
        }

        // Finally, add the question to the complete list of questions.
        questions.Add(question);
    }
}

当然,这段代码相当快速和基本(当然需要一些更好的错误处理),但它至少应该说明一个您可能想要使用的简单方法。我确实认为文本文件将是实现诸如此类的简单系统的好方法,因为它们具有人类可读性(在这种情况下 XML 会有点过于冗长,IMO),而且它们与 XML 一样易于解析文件。希望这能让你开始......

于 2009-02-21T15:37:31.260 回答
3

一个很好的起点是Microsoft 关于 FileStream 的文档

一个快速的谷歌搜索会给你几乎你需要的一切。这是一个关于在 C# 中读取和写入文件的教程。谷歌是你的朋友。

于 2009-02-21T14:53:24.377 回答
2

关于如何构建 txt 文件的任何建议(我如何将答案标记为正确的答案?)

也许最简单的是使用简单的文本文件格式——每一行都有问题和答案(没有空行)。# 号表示正确答案。

文件格式——

问题
#回答
回答
回答
回答  

一个示例文件 -

什么是 1 + 1?
#2
9
3
7
谁被埋在格兰特的坟墓里?
埃德
约翰
#授予
蒂姆

我正在寻找有关如何使用外部文件中的数据在 C# 中创建简单测验的示例代码/算法/教程。

下面是一些使用示例文件创建测验的代码。


        static void Main(string[] args)
        {
            int correct = 0;
            using (StreamReader sr = new StreamReader("C:\\quiz.txt"))
            {
                while (!sr.EndOfStream)
                {
                    Console.Clear();
                    for (int i = 0; i < 5; i++)
                    {
                        String line = sr.ReadLine();
                        if (i > 0)
                        {                            
                            if (line.Substring(0, 1) == "#") correct = i;
                            Console.WriteLine("{0}: {1}", i, line);
                        }
                        else
                        {
                            Console.WriteLine(line);
                        }
                    }                                       

                    for (; ; )
                    {
                        Console.Write("Select Answer: ");
                        ConsoleKeyInfo cki = Console.ReadKey();
                        if (cki.KeyChar.ToString() == correct.ToString())
                        {
                            Console.WriteLine(" - Correct!");
                            Console.WriteLine("Press any key for next question...");
                            Console.ReadKey();
                            break;
                        }
                        else
                        {
                            Console.WriteLine(" - Try again!");
                        }
                    }
                }
            }
        }
于 2009-02-21T16:25:13.393 回答