5

I am trying to read a text file in C# and add line numbers to the lines.

This my input file:

    This is line one
    this is line two
    this is line three

And this should be the output:

    1 This is line one
    2 this is line two
    3 this is line three

This is my code so far:

class Program
{
    public static void Main()
    {
        string path = Directory.GetCurrentDirectory() + @"\MyText.txt";

        StreamReader sr1 = File.OpenText(path);

        string s = "";

        while ((s = sr1.ReadLine()) != null)           
        {
            for (int i = 1; i < 4; i++)
                Console.WriteLine(i + " " + s);
            }

            sr1.Close();
            Console.WriteLine();    
            StreamWriter sw1 = File.AppendText(path);
            for (int i = 1; i < 4; i++)
            {
                sw1.WriteLine(s);
            }

            sw1.Close();               
    }
}

I am 90% sure I need to use for cycle to get the line numbers there but so far with this code I get this output in the console:

1 This is line one
2 This is line one
3 This is line one
1 this is line two
2 this is line two
3 this is line two
1 this is line three
2 this is line three
3 this is line three

And this is in the output file:

This is line number one.
This is line number two.
This is line number three.1 
2 
3 

I am not sure why the string variable s is not used when writing in the file even though it is defined earlier (another block, another rules maybe?).

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Vojtech
  • 643
  • 3
  • 16
  • 30
  • 1
    general comment: I think it is better to have using(StreamReader){} and using(StreamWriter){} block. And also you should name your variable 's' 'line', this is clearer, because it is a line :) – Baptiste Pernet Oct 05 '11 at 10:20
  • 1
    I don't know if this is a problem with the question or your code, but your brackets don't match. The while loop is closed earlier than you might think from your indentation. – Ray Oct 05 '11 at 10:20
  • 1
    Why do you keep looping from `1` to `4`? Do you want to repeat each line four times? – Dan Abramov Oct 05 '11 at 10:21
  • @Dan Abramov no, i think I need a for cycle for numbering the lines, but that is my impression of the solution and I have been wrong before – Vojtech Oct 05 '11 at 10:26
  • @Baptiste Pernet: A comment on editing - I noticed in your edit that you actually added in a curly brace which changes the meaning and execution of the program. Be careful when fixing formatting that you don't fix other things as well. :) – Chris Oct 05 '11 at 10:34
  • Giuseppe has the correct way to do what you want. – Bastardo Oct 05 '11 at 10:35
  • Opening brace for first for loop is missing :P so code wont compile :D – Zenwalker Oct 05 '11 at 10:40
  • 2
    +1 for attempting the homework question and showing the code. So many homework questions are in the form of "give me teh codez" with no effort made at all – RichK Oct 05 '11 at 11:08
  • @zenwalker: the code will compile actually because the braces are all matched, just not necessarily where you'd expect at a glance. And this is necessary to explain why there is no line outputted to the file and why that for loop only runs once. – Chris Oct 05 '11 at 11:08

9 Answers9

2
IEnumerable<string> lines = File.ReadLines(file)
                                .Select((line,i)=>i + " " + line)
                                .ToList();
File.WriteAllLines(file, lines);
Muhammad Hasan Khan
  • 34,648
  • 16
  • 88
  • 131
2
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace AppendText
{
    class Program
    {
        public static void Main()
        {
            string path = Directory.GetCurrentDirectory() + @"\MyText.txt";

            StreamReader sr1 = File.OpenText(path);


            string s = "";
            int counter = 1;
            StringBuilder sb = new StringBuilder();

            while ((s = sr1.ReadLine()) != null)
            {
                var lineOutput = counter++ + " " + s;
                Console.WriteLine(lineOutput);

                sb.Append(lineOutput);
            }


            sr1.Close();
            Console.WriteLine();
            StreamWriter sw1 = File.AppendText(path);
            sw1.Write(sb);

            sw1.Close();

        }

    }
}
Giuseppe Romagnuolo
  • 3,362
  • 2
  • 30
  • 38
  • In homework questions it is usual not to give a full solution to the problem. Also your program is concatenating the new text to the old which is clearly not desired. – Chris Oct 05 '11 at 10:37
  • I have managed to change it that now it creates a new file using: StreamWriter sw1 = File.CreateText(Mytext2.txt); So now it creates a new file. However. The output in the newly created file is on one line. I know I have to change the code inside the stringbuilder class, and I am able to insert characters to the line: sb.Append("testing " + lineOutput); and they appear in front of every line sentence, but when I want to insert \n for new line it doesnt work. – Vojtech Oct 05 '11 at 10:48
  • 2
    @Chris, sorry did not realise it was homework. Deleting my post will do?! :) – Giuseppe Romagnuolo Oct 05 '11 at 10:48
  • never mind, i figured it out -> System.Environment.NewLine :) thanks for the help! – Vojtech Oct 05 '11 at 10:53
  • @GiuseppeR: not worth deleting IMO since it looks like a valid answer. I figured with your rep that you may not have been around long enough to pick this up which is why I flagged it up. And the OP has seen it now so its too late to worry. Hopefully he will read and understand your code rather than just copying and pasting it in though. :) – Chris Oct 05 '11 at 11:06
  • @Chris yes, i have read the code and now i see where i was making the mistake. I altered the code further to suite my needs more, as you can read above. Thank you for your help :) – Vojtech Oct 05 '11 at 12:19
  • @Vojtech: good stuff. For the line breaks you may want to look at the AppendLine methods on both StreamWriter and StringBuilder. It saves you needing to worry about newlines yourself. You may also be interested in File.WriteAllLines in which you store your lines in a List or array or similar and then just use that static method to write them all out to a given path. My preference would be for the latter since I suspect it would make nicer looking code. :) – Chris Oct 05 '11 at 14:47
1

OPEN STREAM

read the whole line and store it in a temp variable. Use a counter to keep track which line you have read. concatenate the counter with the temp variable. save it to the file. move your line pointer to next line and repeat.

THEN CLOSE YOUR STREAM

Jawad Amjad
  • 2,532
  • 2
  • 29
  • 59
1

I could provide you the right code, but because it is home work I will just ask you question that should lead you to the right answer:

  • why do you close the StreamReader the while inside your loop ? You will still access it after, that can cause an error.
  • why do you write in your StreamWriter without the prepended index ?
  • Why do you open the StreamWriter inside the loop ? Wouldn't it be better to open the StreamWriter and StreamReader outside the loop. Do you job in the loop and then close the Streams ?
Baptiste Pernet
  • 3,318
  • 22
  • 47
0

An alternative to @Hasan's answer for in-memory strings as a one-liner:

function AddLineNumbers(string input) => 
    String.Join('\n', input.Split('\n').Select((text, i) => $"{i+1}: {text}"));
Isolin
  • 845
  • 7
  • 20
0

You need to prepend the line number to each line string. Check out String.Format. Also, try a counter variable that sits outside the while loop to keep the line number count.

Hopefully that's enough to get you on the right path without handing you the exact answer.

Polynomial
  • 27,674
  • 12
  • 80
  • 107
0

Are you sure you want to close stream inside the loop while?

Pete Houston
  • 14,931
  • 6
  • 47
  • 60
0

Watch out the FOR loops, you put them inside the While, so basically you are saying:

while ((s = sr1.ReadLine()) != null)

Every row read

for (int i = 1; i < 4; i++)

Repeat 3 times a write.

Also, you are closing the stream inside the while, so after the first row read.

Dippi
  • 377
  • 1
  • 8
0

Here is one major issue for you:

        for (int i = 1; i < 4; i++)
            Console.WriteLine(i + " " + s);
        }

You are closing the for loop with a curly brace but not using a curly brace to open it. This means that the curly brace quoted above is actually closing the while loop so you loop through doing all the console.writeline and then when you come to writing to the file you are actually not reading from the file at all - s is "" due to scoping.

Chris
  • 27,210
  • 6
  • 71
  • 92
  • the closing curly brace belongs to the while loop (indentation is wrong), the for loop does not have both curly braces. – Giuseppe Romagnuolo Oct 05 '11 at 10:48
  • 1
    @Giuseppe R: I would think it more likely that in fact the brackets are wrong rather than the while loop being ended there intentionally but I am happy to stand corrected. Either way there is definitely a mistake there since the while loop couldn't do anything useful since clearly the actions you want to write it to a file have to be done for each line read. – Chris Oct 05 '11 at 11:05