在文本文件中随机选择一行c#streamreader

发布于 2024-10-16 11:25:00 字数 785 浏览 7 评论 0原文

您好,我正在读取一个文本文件,并希望将每一行放入一个单独的变量中。据我所知,我的编程课程数组不能是动态的。因此,如果我设置 15 个数组,并且文本文件有 1000 行,我可以做什么以及如何实现它。

问题是只需要一根线,但我希望随机选择该线。 linetext 是整个文本文件,每个请求末尾都附加了 \r\n。

也许随机选择 \r\n 然后数到 4 并在其后面添加字符串,直到下一个 \r\n。这个想法的问题是被调用的字符串也将包含 \ 所以有什么想法吗?

if (crawler == true)
   {
            TextReader tr = new StreamReader("textfile.txt");
            while (tr.Peek() != -1)
            {
                linktext = linktext + tr.ReadLine() + "\r\n";
            }

            //link = linktext;

            hi.Text = linktext.ToString();

            timer1.Interval = 7000; //1000ms = 1sec 7 seconds per cycle
            timer1.Tick += new EventHandler(randomLink); //every cycle randomURL is called.
            timer1.Start(); // start timer.
        }

Hi I am reading from a text file and would like each line to be put into a seperate variable. From what I remember from my programming classes arrays cannot be dynamic. So if I set 15 arrays, and the text file has 1000 lines what can I do and how do I implement it.

The thing is only one line will be needed but I want the line to be randomly selected. the linetext is the whole text file with \r\n appended to the end of every request.

Maybe randomly select the \r\n then count 4 and add the string after it till the next \r\n. The problem with this idea is the strings getting called will also contain \ so any ideas?

if (crawler == true)
   {
            TextReader tr = new StreamReader("textfile.txt");
            while (tr.Peek() != -1)
            {
                linktext = linktext + tr.ReadLine() + "\r\n";
            }

            //link = linktext;

            hi.Text = linktext.ToString();

            timer1.Interval = 7000; //1000ms = 1sec 7 seconds per cycle
            timer1.Tick += new EventHandler(randomLink); //every cycle randomURL is called.
            timer1.Start(); // start timer.
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

表情可笑 2024-10-23 11:25:00

File.ReadAllLines(...) 将读取给定的每一行文件到字符串数组中。我认为这应该是你想要的,但你的问题有点难以理解。

File.ReadAllLines(...) will read every line of the given file into an array of strings. I think that should be what you want but your question is kind of hard to follow.

恋竹姑娘 2024-10-23 11:25:00

您不需要一次在内存中保留两行以上...您可以使用一个偷偷摸摸的技巧:

  • 创建 Random 的实例,或将一个作为参数
  • 读取第一行。这会自动成为“当前”行以返回
  • 读取第二行,然后调用Random.Next(2)。如果结果为 0,则将第二行设为“当前”行
  • 读取第三行,然后调用 Random.Next(3)。如果结果为 0,则将第三行设为“当前”行
  • ...等等
  • 当到达文件末尾时(reader.ReadLine 返回 null)返回“当前”行。

以下是 IEnumerable 的一般实现 - 如果您使用的是 .NET 4,则可以使用 File.ReadLines() 获取 IEnumerable< string> 传递给它。 (这个实现比实际需要的要多一些 - 它针对 IList 等进行了优化。)

public static T RandomElement<T>(this IEnumerable<T> source,
                                 Random random)
{
    if (source == null)
    {
        throw new ArgumentNullException("source");
    }
    if (random == null)
    {
        throw new ArgumentNullException("random");
    }
    ICollection collection = source as ICollection;
    if (collection != null)
    {
        int count = collection.Count;
        if (count == 0)
        {
            throw new InvalidOperationException("Sequence was empty.");
        }
        int index = random.Next(count);
        return source.ElementAt(index);
    }
    ICollection<T> genericCollection = source as ICollection<T>;
    if (genericCollection != null)
    {
        int count = genericCollection.Count;
        if (count == 0)
        {
            throw new InvalidOperationException("Sequence was empty.");
        }
        int index = random.Next(count);
        return source.ElementAt(index);
    }
    using (IEnumerator<T> iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            throw new InvalidOperationException("Sequence was empty.");
        }
        int countSoFar = 1;
        T current = iterator.Current;
        while (iterator.MoveNext())
        {
            countSoFar++;
            if (random.Next(countSoFar) == 0)
            {
                current = iterator.Current;
            }
        }
        return current;
    }
}

You don't need to keep more than two lines in memory at a time... there's a sneaky trick you can use:

  • Create an instance of Random, or take one as a parameter
  • Read the first line. This automatically becomes the "current" line to return
  • Read the second line, and then call Random.Next(2). If the result is 0, make the second line the "current" line
  • Read the third line, and then call Random.Next(3). If the result is 0, make the third line the "current" line
  • ... etc
  • When you reach the end of the file (reader.ReadLine returns null) return the "current" line.

Here's a general implementation for an IEnumerable<T> - if you're using .NET 4, you can use File.ReadLines() to get an IEnumerable<string> to pass to it. (This implementation has a bit more in it than is really needed - it's optimized for IList<T> etc.)

public static T RandomElement<T>(this IEnumerable<T> source,
                                 Random random)
{
    if (source == null)
    {
        throw new ArgumentNullException("source");
    }
    if (random == null)
    {
        throw new ArgumentNullException("random");
    }
    ICollection collection = source as ICollection;
    if (collection != null)
    {
        int count = collection.Count;
        if (count == 0)
        {
            throw new InvalidOperationException("Sequence was empty.");
        }
        int index = random.Next(count);
        return source.ElementAt(index);
    }
    ICollection<T> genericCollection = source as ICollection<T>;
    if (genericCollection != null)
    {
        int count = genericCollection.Count;
        if (count == 0)
        {
            throw new InvalidOperationException("Sequence was empty.");
        }
        int index = random.Next(count);
        return source.ElementAt(index);
    }
    using (IEnumerator<T> iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
        {
            throw new InvalidOperationException("Sequence was empty.");
        }
        int countSoFar = 1;
        T current = iterator.Current;
        while (iterator.MoveNext())
        {
            countSoFar++;
            if (random.Next(countSoFar) == 0)
            {
                current = iterator.Current;
            }
        }
        return current;
    }
}
初与友歌 2024-10-23 11:25:00

List是动态的扩大名单。您可能想使用它而不是数组。

如果只有 1000 个元素,只需将它们读入列表并选择一个随机元素。

A List<T> is a dynamically expanding list. You might want to use that instead of an array.

If there is only 1000 elements, just read them into the list and select a random element.

无需解释 2024-10-23 11:25:00

关于数组的事情..你可以使用 List<>相反,它是动态的

下面是如何实现这一点的示例:

public static string GetRandomLine(ref string file) {
    List<string> lines = new List<string>();
    Random rnd = new Random();
    int i = 0;

    try {
        if (File.Exists(file)) {
            StreamReader reader = new StreamReader(file);
            while (!(reader.Peek() == -1))
                lines.Add(reader.ReadLine());
            i = rnd.Next(lines.Count);
            reader.Close();
            reader.Dispose();
            return lines[i].Trim();
        }
        else {
            return string.Empty;
        }
    }
    catch (IOException ex) {
        MessageBox.Show("Error: " + ex.Message);
        return string.Empty;
    }
}

Regarding the array thing.. you could use a List<> instead, which is dynamic

Here is an example of how this can be achieved:

public static string GetRandomLine(ref string file) {
    List<string> lines = new List<string>();
    Random rnd = new Random();
    int i = 0;

    try {
        if (File.Exists(file)) {
            StreamReader reader = new StreamReader(file);
            while (!(reader.Peek() == -1))
                lines.Add(reader.ReadLine());
            i = rnd.Next(lines.Count);
            reader.Close();
            reader.Dispose();
            return lines[i].Trim();
        }
        else {
            return string.Empty;
        }
    }
    catch (IOException ex) {
        MessageBox.Show("Error: " + ex.Message);
        return string.Empty;
    }
}
雪若未夕 2024-10-23 11:25:00

如果您创建文件,那么理想的方法是预先存储有关文件的元数据,例如行数,然后决定选择哪个“随机”行。

否则,你无法通过不使用它们来解决“数组”问题。而是使用存储任意数量字符串的列表。之后,选择一个随机数就像生成一个介于 0 和列表大小之间的随机数一样简单。

你的问题以前已经解决过,我建议谷歌搜索“C# read random line from file”。

If you create the file then the ideal way would be to store meta data about the file, like the number of lines, before hand, and then decide which 'random' line to choose.

Otherwise, you cant get around the "array" problem by not using them. Instead use a List which stores any number of strings. After that picking a random one is as simple as generating a random number between 0 and the size of the list.

Your problem has been done before, I recommend googling for "C# read random line from file".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文