John McDonald
John McDonald

Reputation: 71

StreamReader does not read in carriage returns

I have to write a console application for a computer course that I'm taking. The program reads text in from a file using StreamReader, splits the string into single words and saves them in a String array and then prints the words out backwards.

Whenever there is a carriage return in the file, the file stops reading in the text. Could anyone help me with this?

Here is the main program:

using System;
using System.IO;
using System.Text.RegularExpressions;

namespace Assignment2
{
    class Program
    {
        public String[] chop(String input)
        {
            input = Regex.Replace(input, @"\s+", " ");
            input = input.Trim();

            char[] stringSeparators = {' ', '\n', '\r'};
            String[] words = input.Split(stringSeparators);

            return words;
        }

        static void Main(string[] args)
        {
            Program p = new Program();

            StreamReader sr = new StreamReader("input.txt");
            String line = sr.ReadLine();

            String[] splitWords = p.chop(line);

            for (int i = 1; i <= splitWords.Length; i++)
            {
                Console.WriteLine(splitWords[splitWords.Length - i]);
            }

            Console.ReadLine();

        }
    }
}

And here is the file "input.txt":

This is the file you can use to 
provide input to your program and later on open it inside your program to process the input.

Upvotes: 4

Views: 6737

Answers (3)

Gloria
Gloria

Reputation: 1053

You are just reading in one line. You need to read all lines till end of file. The following should work:

    String line = String.Empty;
    using (StreamReader sr = new StreamReader("input.txt"))
    {
        while (!sr.EndOfStream)
        {
            line += sr.ReadLine();
        }
    }

Upvotes: 3

evanmcdonnal
evanmcdonnal

Reputation: 48076

The problem is that you're calling ReadLine() which does exactly that, it reads til it encounters a carriage return (you have to call it in a loop).

Typically if you want to read a file line by line with StreamReader the implementation looks more like this (from msdn);

        using (StreamReader sr = new StreamReader("TestFile.txt")) 
        {
            string line;
            // Read and display lines from the file until the end of  
            // the file is reached. 
            while ((line = sr.ReadLine()) != null) 
            {
                Console.WriteLine(line);
            }
        }

The condition in the while loop ensures that you will read til the end of the file because ReadLine will return null if there is nothing to read.

Another option is just to use File.ReadAllLines(MyPath) which will return an array of strings, each element being one line in the file. To give a more complete example of that;

  string[] lines = File.ReadAllLines(MyFilePath);
  foreach(string line in lines)
  {
        string[] words = line.Split(' ').Reverse();
        Console.WriteLine(String.Join(" ", words));
  }

Those three lines of code do the following; Reads the entire file into a string array where each element is a line. Loops over that array, on each line we split it into the words and reverse their order. Then I join all the words back together with spaces between them and print it to the console. If you want the whole file in reverse order then you need to start at the last line instead of the first, I'll leave that detail to you.

Upvotes: 2

Reed Copsey
Reed Copsey

Reputation: 564333

You can use StreamReader.ReadToEnd instead of StreamReader.ReadLine.

// Cange this:
// StreamReader sr = new StreamReader("input.txt");
// String line = sr.ReadLine();

string line;
using (StreamReader sr = new StreamReader("input.txt"))
{
    line = sr.ReadToEnd();
}

The addition of the using block will make sure the input file is closed properly, as well.

Another alterantive would just be to use:

string line = File.ReadAllText("input.txt"); // Read the text in one line

ReadLine reads a single line from the file, and strips off the trailing carraige return and line feed characters.

ReadToEnd will read the entire file as a single string, and preserve those characters, allowing your chop method to work as written.

Upvotes: 3

Related Questions