2

I'm trying to update some part of a string in a file. Currently my code is:

FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(filePath);

string[] line = sr.ReadToEnd().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
List<string> lines = new List<string>();

string eventName = ','+eventNameUpdateTextBox.Text.ToString()+',';
foreach (var l in line)
{
    if (l.Contains(eventName))
    {
        int start = l.IndexOf(eventName);
        l.Remove(start, eventName.Length);
        l.Insert(start, newNameTextBox.Text.ToString());
        lines.Add(l);
    }
    else
    {
        lines.Add(l);
    }   
}

string toCsvOutput = string.Join(Environment.NewLine, lines.ToArray());

But the result I'm getting is the same file as before.
When I try to debug it, I see that function:

  l.Insert(start, newNameTextBox.Text.ToString());

Does not change string and returns the same string as at the beginning. Why does this happen? Where am I wrong?

d219
  • 2,707
  • 5
  • 31
  • 36
hbk
  • 10,908
  • 11
  • 91
  • 124

3 Answers3

2

Strings are immutable, that means they cannot change. You need to create a new string and assign this to the variable.

l = l.Remove(start, eventName.Length);
l = l.Insert(start, newNameTextBox.Text.ToString()); 

MSDN:

Strings are immutable--the contents of a string object cannot be changed after the object is created, although the syntax makes it appear as if you can do this.

Why .NET String is immutable?

Community
  • 1
  • 1
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
1

function on strings return the result strings, but do not change the value of the string(most of them if not all)

try this:

    FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
    StreamReader sr = new StreamReader(filePath);

    string[] line = sr.ReadToEnd().Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
    List<string> lines = new List<string>();

    string eventName = ','+eventNameUpdateTextBox.Text.ToString()+',';
    foreach (var l in line)
    {
        if (l.Contains(eventName))
        {
            int start = l.IndexOf(eventName);
            l = l.Remove(start, eventName.Length);
            l = l.Insert(start, newNameTextBox.Text.ToString());
            lines.Add(l);
        }
        else
        {
            lines.Add(l);
        }   
    }
    string toCsvOutput = string.Join(Environment.NewLine, lines.ToArray());
No Idea For Name
  • 11,411
  • 10
  • 42
  • 70
1

You have to assign the changes to a new (string) variable. This string variable cannot be l because is the one being iterated in the foreach loop and thus cannot be changed. You have to rely on a temporary variable, as shown in the code below.

foreach (var l in line)
{
    if (l.Contains(eventName))
    {
        string temp = l;
        int start = l.IndexOf(eventName);
        temp = temp.Remove(start, eventName.Length);
        temp = temp.Insert(start, newNameTextBox.Text.ToString());
        lines.Add(temp);
    }
    else
    {
        lines.Add(l);
    }
}
varocarbas
  • 12,354
  • 4
  • 26
  • 37
  • now it's changing, but also think i something missed in this code - now it's return string with old value+ new value – hbk Aug 26 '13 at 14:24
  • 1
    @krill your code seems to be fine but you can replace the third line inside your condition with temp.Replace(eventName, ""). – varocarbas Aug 26 '13 at 14:26
  • try `temp = l.Replace(eventName, newNameTextBox.Text.ToString());` - now it's work correct – hbk Aug 26 '13 at 14:27
  • @Kirill this too. My previous suggestion was to delete the old string. But if a replacement accounts for both deletion and inclusion, just do it. – varocarbas Aug 26 '13 at 14:29