4

I'm making program that sends email with some data. I know that the System.ArgumentOutOfRangeException exception means that number in the array/list doesn't exist, but i don't know what i coded wrongly.

Here's a code:

public void SendMail()
{
    StreamReader sr = new StreamReader(path1);
    var lineCount = File.ReadLines(path1).Count();
    List<string> data = new List<string>();
    for (int i = 0; i < lineCount; i++)
    {
       data[i] = sr.ReadLine(); //Error Comes here.
    }
    string finaldata = data[0] + "/n" + data[1] + "/n" + data[2] + "/n" + data[3] + "/n" + data[4] + "/n" + data[5] + "/n" +       
    data[6] + "/n" + data[7] + "/n" + data[8] + "/n" + data[9] + "/n" + data[10];
    var fromAddress = new MailAddress("tutorialvideohd@gmail.com", "From Name");
    var toAddress = new MailAddress("tutorialvideohd@example.com", "To Name");
    const string fromPassword = "*****";
    string subject = "Some Users Data.";
    string body = finaldata;

    var smtp = new SmtpClient
    {
       Host = "smtp.gmail.com",
       Port = 587,
       EnableSsl = true,
       DeliveryMethod = SmtpDeliveryMethod.Network,
       UseDefaultCredentials = false,
       Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
    };

    using (var message = new MailMessage(fromAddress, toAddress)
    {
        Subject = subject,
        Body = body
    })
    {
        smtp.Send(message);
    }
}
  • `List data = new List();` create empty list that doesn't have any elements. So when you try `data[i] =` it trows exception. You can fix it: `data.Add(sr.ReadLine())` – George Alexandria Aug 13 '17 at 16:39
  • In think you mean "\n" (newline) instead of "/n" (slash followed by an n). However, according to RFC 2822, section 2 CRLF, i.e. "\r\n", should be used. – ckuri Aug 13 '17 at 16:45
  • @MemesTV: what does the "/n" mean? – code4life Aug 13 '17 at 16:48
  • 3
    Possible duplicate of [ArgumentOutOfRangeException on initialized List](https://stackoverflow.com/questions/4236629/argumentoutofrangeexception-on-initialized-list) – Lance U. Matthews Aug 13 '17 at 16:51
  • @code4life `\n` is newline, it would be better to use `Environment.NewLine` which, at least in every environment I have used would be `\r\n` for carrage return, new line – Andrew Aug 13 '17 at 17:11

4 Answers4

1

When you do this, it's only creating an empty list:

List<string> data = new List<string>();

So if you try to assign a value using an index, you're trying to assign a value to something that doesn't exist.

Instead you should Add() as follows:

data.Add(sr.ReadLine());

EDIT:

Also, unrelated to the question asked, but I don't see you closing the StreamReader you've opened, which is always a bad practice. I suggest, instead, using a using statement which will take care of the opening and closing of the StreamReader for you. Also, getting the lineCount is redundant, you could do something like this taking advantage of the fact that you don't need to set the number of items in a list in advance.

List<string> data = new List<string>();
using (StreamReader sr = new StreamReader(path1))
{
    while(!sr.EndOfStream)
        data.Add(sr.ReadLine()); 
}
Sach
  • 10,091
  • 8
  • 47
  • 84
0

First, you have an empty list of strings, you can't fill data with by accessing the indexes, since those indexes don't yet exist. You have to use data.Add(sr.ReadLine()) to create the new index and add the value in it.

string finaldata = data[0] + "/n" + data[1] + "/n" + data[2] + "/n" + data[3] + "/n" + data[4] + "/n" + data[5] + "/n" +       
data[6] + "/n" + data[7] + "/n" + data[8] + "/n" + data[9] + "/n" + data[10];

Hardcoded IDs will mean you need at least 11 items in the list and it will break if you have less. Why don't you do this instead?

string finalData = String.Join("/n", data);

This way it joins your list of strings, using the newline as a separator and doesn't matter if you have more or less items in the list.

Andrew
  • 1,544
  • 1
  • 18
  • 36
  • @GeorgeAlexandria Yes, both parts need to be fixed, the finalData will still throw an exception if the stream didn't have 11 lines. – Andrew Aug 13 '17 at 16:43
0

You are setting an item in the array list that has not yet been initialized. Use the following line where the exception is thrown.

data.Add(sr.ReadLine());
tonybasran
  • 112
  • 4
-1

You are doing the same thing twice.

This block of code:

StreamReader sr = new StreamReader(path1);
// ... you had some code here, but not relevant to the point...
for (int i = 0; i < lineCount; i++)
{
    data[i] = sr.ReadLine(); //Error Comes here.
}

Populates the list data with a bunch of strings.

This block of code:

var lineCount = File.ReadLines(path1).ToList();

Populates lineCount with exactly the list of strings that you're trying to fill into data.

So just do this:

StreamReader sr = new StreamReader(path1);
var lineCount = File.ReadLines(path1).Count();
List<string> data = lineCount;

And get rid of this block of code:

for (int i = 0; i < lineCount; i++)
{
    data[i] = sr.ReadLine(); //Error Comes here.
}

And notice how data is now properly filled in. You really don't need to have that StreamReader either, but hey, I don't want to rewrite your entire body of code at this point.

Key takeaway: read the documentation, try to understand what each function call is doing, especially the .NET Framework ones.

code4life
  • 15,655
  • 7
  • 50
  • 82
  • `.Count()` never returns a list of strings, it returns the number of in this case lines in the file being used for the stream reader. `lineCount` is an int not a list of strings. – Andrew Aug 13 '17 at 17:12
  • @Andrew: yeah, I should have removed the `.Count()` and replaced with `.ToList()`. – code4life Aug 14 '17 at 20:22
  • No problem, part of why I have a dislike of `var` and even more so 'dynamic` in c# code, sure the system understands, but just looking at the code, you have to figure out the type, if it had said `int lineCount = File.ReadLines(path1).Count();` you would have caught it. – Andrew Aug 14 '17 at 20:42
  • @Andrew: the fault wasn't with the `var`, it was with me, LOL. I was too lazy to back-check my code. At the end of the day, you can't blame the compiler or the language idiosyncracies, it's always myself. – code4life Aug 15 '17 at 02:13