www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Main foreach loop fails when another foreach is added

reply ikelaiah <iwan.kelaiah gmail.com> writes:
Hi,

I'm writing a program that reads a text file and launch my work 
URLs in it.
It worked fine, and very happy.

Then I added another `foreach` loop to count total number of 
lines.
After this, the main `foreach` won't work.

Does anyone know as to why this happens?
I might have missed something very obvious.

Thank you.

Regards,
ikel


```d
module openurls;

import std.stdio : writeln, File, KeepTerminator;
import std.file;
import std.range;
import std.ascii;
import std.getopt : getopt, GetoptResult, defaultGetoptPrinter;
import std.process : browse;
import core.thread.osthread;
import core.time;


void main(string[] args)
{
     string input_filename = "";

     // Get command line option
     GetoptResult user_args = getopt(args,
         "input|i", "A list of URLs separated by new lines.", 
&input_filename);

     // Does user need help?
     if (user_args.helpWanted)
     {
         defaultGetoptPrinter("Command line options for Open 
URLs.",
             user_args.options);
     }

     // Is input file specified?
     if (input_filename.length == 0)
     {
         writeln("Open URL: No file specified.\n");
         defaultGetoptPrinter("Command line option for Open URLs.",
             user_args.options);
         return;
     }

     // Does the file exist?
     if (!input_filename.exists)
     {
         writeln("Open URL: input file --" ~ input_filename ~ "-- 
does not exist.\n");
         return;
     }
     else
     {
         writeln("Open URL: reading --" ~ input_filename ~ "--");
     }

     // Open input file for reading
     size_t line_count = 0;
     File input_file = File(input_filename);
     auto file_range = input_file.byLine(KeepTerminator.no, 
std.ascii.newline);

     // if this foreach not commented out
     // the last foreach won't run.
     foreach (char[] line; file_range)
     {
         line_count += 1;
     }

     // the MAIN foreach loop
     // -- won't run if above foreach is enabled
     foreach (char[] line; file_range)
     {
         if (!line.empty)
         {
             writeln("Open URL: " ~ line);
             Thread.sleep(dur!("seconds")(2));
             browse(line);
         }
     }

     writeln("Open URL: completed");

     writeln("Closing " ~ input_filename);
     input_file.close();
}

```
Aug 07 2022
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 8/7/22 10:11 PM, ikelaiah wrote:
 Hi,
 
 I'm writing a program that reads a text file and launch my work URLs in it.
 It worked fine, and very happy.
 
 Then I added another `foreach` loop to count total number of lines.
 After this, the main `foreach` won't work.
 
 Does anyone know as to why this happens?
 I might have missed something very obvious.
 
 Thank you.
 
 ```d
...
      // Open input file for reading
      size_t line_count = 0;
      File input_file = File(input_filename);
Here you open the file
      auto file_range = input_file.byLine(KeepTerminator.no, 
 std.ascii.newline);
And then wrap it in a byline range.
 
      // if this foreach not commented out
      // the last foreach won't run.
      foreach (char[] line; file_range)
      {
          line_count += 1;
      }
For this foreach loop, you read every line in the file, exhausting the file (the input stream for the file is empty).
 
      // the MAIN foreach loop
      // -- won't run if above foreach is enabled
      foreach (char[] line; file_range)
      {
          if (!line.empty)
          {
              writeln("Open URL: " ~ line);
              Thread.sleep(dur!("seconds")(2));
              browse(line);
          }
      }
And now, you tried to read it again! Which means you are trying to read more data from an empty stream. You need to either a) reopen the file, or b) do both in the same loop.
 ```
-Steve
Aug 07 2022
parent ikelaiah <iwan.kelaiah gmail.com> writes:
On Monday, 8 August 2022 at 02:45:54 UTC, Steven Schveighoffer 
wrote:

 And now, you tried to read it again! Which means you are trying 
 to read more data from an empty stream.

 You need to either a) reopen the file, or b) do both in the 
 same loop.


 -Steve
Steve! You are Legend! **Thank you**. It is obvious now the second `foreach` is reading from an empty stream! Regards, ikel
Aug 07 2022