## GizmoPower

Hello.
I am making a win app wich I can use to replace values in a .ini file.

In this example.ini file I want to change the values after the =

location
{
x=0.35
y=0.56
z=-0.5
}

I have label1, 2, 3 with text: "x, y, z" and want to get values after =. to texBox1, 2, 3 wich I then can replace and send back. This with 2 buttons with text: Get value, Return value.

I have tried this code but dosent work for me becouse the values are not always on the same lines in the different .ini files.

I dont have anything yet for saving the value back to the string

string[] arrLines = strAllFile.Split(new char[] { '\n' });
textBox1.Text = arrLines [375];
textBox2.Text = arrLines[397];
textBox3.Text = arrLines[370];

I am complete noob, but reading and learning everyday. I would appreciate if someone could help me out a bit!

## Mitja Bonca 557

This is the only text you have in the file:
location
{
x=0.35
y=0.56
z=-0.5
}

??

or there is more, and you want to 1st find the text "Location" and th values inside brackets?

## GizmoPower

Hello and tanx for replying.

No the .ini file can be around 1000 lines and the values can be anywhere within the .ini file. That is why I need to get the values (There are many) by name inside example.ini and not lines.
No I dont need Location. I only need the actual value to textbox, edit value and send it back. "X=" is already text of a label1.

Maybe I have gone all wrong with the textBox thing?
Possible I should use xml. I´ve read some about it but...?

I would be really happy to get some hints! :D

## Mitja Bonca 557

I dont think I can understand you.
Tell me, what is that you are looking for EXACTLY?
Are this only values of X,Y and Z?

If so, are these the only x,y and z in the ini file?
Please, id you need help, I would expect a better understandable explanation.

Mitja

## GizmoPower

Sorry about that. Maybe I am not explaining myself god enough! :)
You are totally right about that there is more x, y, z inside the ini file and therfore I need to find location and then get the values inside the bracket. I will attach here an car.ini file.
I dont want every value but just some important as supension values, engine values, differential and so on.
I will attach a picture og my app.

I hope this makes more sence!

## ddanbe 2,720

You need some sort of scanner, lexer or tokenizer to get the values you want.
If you have the file in a string you can use Remove and Insert methods of the string class.

## Mitja Bonca 557

Ok, I new I was right :)
Anyway, so there is plenty of "NAMES" with their values.
What we need to do, is like ddanbe said, we need some sort of tokenizer to get thw wanted values - and then they need to go back to the same place from where they were taken.

One question:
The pattern is like you said:
NAME1
{
value1
value2
value3
and so on...
}
NAME2
{
value1
value2
value3
and so on...
}

so, how do I know which name to look for?
Just answer me on these 2 questions, and Ill try to do the code for you.

Mitja

## GizmoPower

I really appreciate you taking time to help me. Tanx!

And yes it is exactly what I was trying to explain! :)

I am not sure about what you mean with wich name.

Off curse like you said earlier it has to find first: Name1 then the value1 to textBox1 value2 to textBox2 value3 to textBox3.

Like here It needs to find "susp_front" and then get the values of "restlen", "minlen" and "maxlen" to "textBox1", "textBox2", "textBox3" and so on.
The same with susp_rear.

susp_front
{
y=0
z=1.599
restlen=0.142 ;0.1m RL, 3625N load
minlen=0.005
maxlen=0.16
bumpstop_len=0.04
bumpstop_k=70000
k=86150
}
}
susp_rear
{
y=0
z=-1.066
restlen=0.146 ;0.09m RL, 5005N load
minlen=0.005
maxlen=0.16
bumpstop_len=0.04
bumpstop_k=70000
k=89375

}
}

I am going to do the same with engine, differential etc. values.

I hope that made sence..?

Tanx again for helping me out! :)

## Mitja Bonca 557

Why do you have 2 closing brackets:
susp_front
{
y=0
z=1.599
restlen=0.142 ;0.1m RL, 3625N load
minlen=0.005
maxlen=0.16
bumpstop_len=0.04
bumpstop_k=70000
k=86150
}
}

## Mitja Bonca 557

I did an import of data. This is my example file:
Name1
{
x=1
y=2,4
z=3,6
}
Name2
{
x=4,5
y=2
z=6
}
Name3
{
x=7,4
y=5,4
z=5
}
Name4
{
x=5,2
y=6
z=7,3
}
(

(so that you wont wonder where from I get "Name1" - its only an example).
I even included label (beside textBoxes) to get auto-named, depending on the name which is on the left side of the equalizer ("="). This is the code:

namespace Jan28FindIn_TextFile
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void buttonGet_Click(object sender, EventArgs e)
{
string tag = "Name2";
string tagEnd = "}";
string path = Environment.CurrentDirectory + @"\text7.txt";
string allText = System.IO.File.ReadAllText(path);
string[] array = allText.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
int start = (Array.IndexOf(array, tag)) + 2;
int end = 0;
for (int i = start; i < allText.Length; i++)
{
string item = array[i];
if (item == tagEnd)
{
end = i;
break;
}
}

TextBox[] textBoxes = new TextBox[] { textBox1, textBox2, textBox3, textBox4, textBox5 };
Label[] labels=new Label[]{label1,label2,label3,label4,label5};

//empty the labels and textBoxes before filling it:
for (int c = 0; c < textBoxes.Length; c++)
{
textBoxes[c].Text = String.Empty;
labels[c].Text = String.Empty;
}

//populating labels and textBoxes from the appropriate content:
int counter = 0;
for (int i = start; i < end; i++)
{
string[] divide = array[i].Split('=');
labels[counter].Text = divide[0];
textBoxes[counter++].Text = divide[1];
}
}
}
}

I will try to do an insertion now too.
Mitja

commented: Nice effort! +8

## GizmoPower

I am really looking forward to try this! :) At work right now.
Tanx again Mitja.

## Mitja Bonca 557

restlen=0.142 ;0.1m RL, 3625N load

Do you want to show all in a textBox, or only to sign ";", so only this:0.142
or all the string

## GizmoPower

Yes, only 0.142
Ive tried youre code and it works just like I wanted!
But: I get this error code if I try it with the .ini file I posted.

System.IndexOutOfRangeException: Index was outside the bounds of the array.
at test3.MainForm.Button13Click(Object sender, EventArgs e) in c:\Program Files\SharpDevelop\Test3\Test3\MainForm.cs:line 358
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at test3.Program.Main(String[] args) in c:\Program Files\SharpDevelop\Test3\Test3\Program.cs:line 27

## Mitja Bonca 557

The code for exporting all the values from the file for any kind is now working well. Dont worry or those errors now.
Now iam considering how to do the import - send data back to file to the correct spot. Do you have any idea?
This is a hard task you know. Will take more then then the other.

## GizmoPower

Well as I stated in my first post I am very noob at this but learning more everyday thanks to guys like you! :)
I dont have a clue on how to send data back to the correct spot.
I wish I knew couse this is very interesting.
Tanx for trying Mitja, I really apreciate it!

## Mitja Bonca 557

I will do it, but I am considering th best option. Its not simple, but not impossible. Will do it for sure.

## GizmoPower

Tanx a lot Mitja! I am sure it will work great:)

## Mitja Bonca 557

This is the whole code. The only thing you have to take care of, is to get the string of the tag (tag is the name of the object you want to edit - in out example this would be "susp_front"). Or you will set this variable to a tabContol or on some radioButton - its up to you.
And you have to make sure how many textBoxes and lables would you like to have for eact object. You can do a seperated method which would show the exact amount of textBoxes and labels (if you want it to make all automatic). But this is going into a very details.

PS: one more thing: in the method "PopulatingText" you will see I do an array of textBoxes and lables - these are the controls which I putted on the form in a designer, and I operate with them to populate them with appropriate data. With this kind of code you could choose Object by a radio button (front_susp, end_susp,...) and the code will automatically choose how many textBoxes and lables you need (with the appropriate text in each label).

Hope you like it, here it is:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.IO;

namespace Jan28FindIn_TextFile
{
public partial class Form1 : Form
{
string tag;
string path;
string allText;
string originalText;
string modifiedText;

public Form1()
{
InitializeComponent();
}

private void buttonGet_Click(object sender, EventArgs e)
{
//tag - this is something you need to get from somewhere else - from the tab maybe?
tag = "susp_front";
//endTag leav here! its the same for all.
string tagEnd = "}";
path = Environment.CurrentDirectory + @"\test7.txt";

GetOriginalText(allText, tag, tagEnd);
PopulatingText();
}

private void buttonSet_Click(object sender, EventArgs e)
{
try
{
string[] array = GetNewText_ToArray();
GetNewText_ToString(array);
ReplayingTextInFile();
MessageBox.Show("The new text has been successfully inserted into a file.");
}
catch
{
MessageBox.Show("Some error occured during saving text into a file.");
}
}

private void GetOriginalText(string textAll, string tagStart, string tagEnd)
{
int startIndex = textAll.IndexOf(tagStart);
int endIndex = textAll.IndexOf(tagEnd, startIndex);
originalText = textAll.Substring(startIndex, (endIndex - startIndex + 1));
}

private void PopulatingText()
{
string[] array = originalText.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

TextBox[] textBoxes = new TextBox[] { textBox1, textBox2, textBox3, textBox4,
textBox5, textBox6, textBox7, textBox8 };
Label[] labels = new Label[] { label1, label2, label3, label4,
label5, label6, label7, label8 };

//empty the labels and textBoxes before filling it:
for (int c = 0; c < textBoxes.Length; c++)
{
textBoxes[c].Text = String.Empty;
labels[c].Text = String.Empty;
}

//populating labels and textBoxes from the appropriate content:
int counter = 0;
for (int i = 2; i < array.Length - 1; i++)
{
string[] divide = array[i].Split('=');
labels[counter].Text = divide[0];

//if a string contains ";" it needs to get only the string on left habd side:
if (divide[1].Contains(";"))
{
divide = divide[1].Split(';');
//if you have any semicolon (;) in any line, what is on the right side of it, it will appear in brackets!
textBoxes[counter++].Text = divide[0].Trim() + " (" + divide[1] + ")";
}
else
textBoxes[counter++].Text = divide[1];
}
}

private string[] GetNewText_ToArray()
{
string[] array = originalText.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

TextBox[] textBoxes = new TextBox[] { textBox1, textBox2, textBox3, textBox4,
textBox5, textBox6, textBox7, textBox8 };

for (int i = 2; i < array.Length - 1; i++)
{
string[] divide = array[i].Split('=');
array[i] = array[i].Replace(divide[1], textBoxes[i - 2].Text);
}
return array;
}

private void GetNewText_ToString(string[] array)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.Length; i++)
{
if (i < (array.Length - 1))
sb = sb.Append(array[i] + "\r\n");
else
sb = sb.Append(array[i]);
}
modifiedText = sb.ToString();
}

private void ReplayingTextInFile()
{
allText = Regex.Replace(allText, originalText, modifiedText);
using (StreamWriter sw = new StreamWriter(path))
{
sw.Write(allText);
}
}
}
}

## GizmoPower

I have got the code working with a test.txt file. Just copied over the "susp_front" and "susp_rear" part But if I try with the car.ini i do get errors. I think it may have to do with the semicolons ; ..? I will do some testing.
Other than that the code is perfect! Really awsome job!
Tanx a lot Mitja!

System.IndexOutOfRangeException: Index was outside the bounds of the array.
at RM.MainForm.PopulatingText() in c:\Users\Valle\Documents\SharpDevelop Projects\RM\RM\MainForm.cs:line 92
at RM.MainForm.Button1Click(Object sender, EventArgs e) in c:\Users\Valle\Documents\SharpDevelop Projects\RM\RM\MainForm.cs:line 46
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at RM.Program.Main(String[] args) in c:\Users\Valle\Documents\SharpDevelop Projects\RM\RM\Program.cs:line 27