So so far what my program does is goes through a file that you specify and takes the lines of text between 2 keywords and saves them to a seperate file for each block of text.
i.e
Start
stuff
stuffer
End
Start1
stuff
stuffer
End
The "stuff" in between will be saved to a diff text file for each block
But what i am trying to do now is instead of using keywords to mark the beginning and end i want to use brackets to mark it.
Start
[
[
stuffer
]
]
End
So the program instead of using Start and End to mark the beginning and end could use the bracket count....wouldnt it be something like:
so that when counter reaches 0 it will know that it has reached the end of a block of code...
this is what I have so far and the file that I have been using for testing
private void button1_Click(object sender, EventArgs e)
{
string path = "c:\\";
int counter = 0;
var masterList = new List<List<string>>();
using (var sr = new StreamReader(path + "test.txt"))
{
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
if (line.StartsWith("CLASS") || line.StartsWith("TYPE"))
{
if (line.Equals("{"))
{
counter = counter + 1;
}
if (line.Equals("}"))
{
counter = counter - 1;
}
var lineList = new List<string>();
while (!line.Equals("END"))
{
lineList.Add(line);
line = sr.ReadLine();
}
masterList.Add(lineList);
}
}
}
foreach (var lineList in masterList)
{
using (var sw = new StreamWriter(path + lineList[0] + "_test.txt"))
{
foreach (string line in lineList)
sw.WriteLine(line);
It seems that you are trying to do more than just count the brackets?
Are asking for an opinion on the code?
Your assertion that by adding when you see a '{' and subtracting when you see a '}' and when counter is 0 indicates the end of a code block, counter = 1 indicates a start of a code block.
If you are asking for opioions on the code there are many many things I would change there, but it looks as though it sould work.
Please use code tags and preserve formatting. To hard to read as is.
As near as I can tell you have some issues in your if statements. Again is hard to read without the proper indentation but it appears that your test for "{" is nested within your test for "Class" which would make it always false as this line of code will never execute unless the first if test is true which means this one is false as is the next one which tests for "}"
You need to change the nesting so that either the tests for class, {, } are in independant if blocks [not mested within the class test] or are in an is else senario.
if (line.StartsWith("CLASS") || line.StartsWith("TYPE"))
{
if (line.Equals("{")) //will never be true
{
counter = counter + 1; // will never execute
}
if (line.Equals("}")) // will never be true
{
counter = counter - 1; // will never execute
}
var lineList = new List<string>();
while (!line.Equals("END"))
{
lineList.Add(line);
line = sr.ReadLine();
}
masterList.Add(lineList);
}
That does not appear to be the only problem but was one that jumped out right away.
You are not doing anything with the counter so other than the fact it was never changing it is also not being used for anything,
I don't know where you might find a line that is equal to "END" if you are working with a real class file as this would be an invalid line.
Not sure what your thought process is here but I would expect the code posted to read until it finds the word class or type at the begining of a line and then write the remainder of the file to the stream.
1. It will find the beginning of a class (im using the regex for this)
2. Store all the code until it gets to the end of the class
3. Somehow use the brackets it mark the end of the class
something like
once it knows that every bracket has a matching one it would stop storing the data and move onto the next bunch of code
the counter would be to store the amount of opening and closing brackets
once the counter reaches 0 then that would mean that every bracket has a corresponding opening and closing one and so since every bracket has a closing one it would be the end of the class
Code:
private void button1_Click(object sender, EventArgs e)
{
string path = "c:\\";
string path2 = System.IO.Path.Combine(@"c:\", "army");
System.IO.Directory.CreateDirectory(path2);
int counter = 0;
Regex regex = new Regex( "^\\s{1,5}public", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled );
var masterList = new List<List<string>>();
using (var sr = new StreamReader(path + "long.txt"))
{
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
if (line.Equals("{"))
{ counter = counter + 1; }
if (line.Equals("}"))
{ counter = counter - 1; }
bool starter =regex.IsMatch(line);
if (starter==true)
{
var lineList = new List<string>();
while (!line.StartsWith("end"))
{
lineList.Add(line);
line = sr.ReadLine();
}
masterList.Add(lineList);
}
}
}
foreach (var lineList in masterList)
{
using (var sw = new StreamWriter(path + lineList[0] + "_test.txt"))
{
foreach (string line in lineList)
sw.WriteLine(line);
textBox1.Text = Convert.ToString(masterList.Count);
}
}
}
}
}
My basic question to a lot of your posts is, what do you want to accomplish with all that. Do you want to create a code parser tool for C#`? Or what is the purpose of all that?
Jonny Poet
To be Alive is depending on the willingsness to help others and also to permit others to help you. So lets be alive. !
Using Code Tags makes the difference: Code is easier to read, so its easier to help. Do it like this: [CODE] Put Your Code here [/code]
If anyone felt he has got help, show it in rating the post.
Also dont forget to set a post which is fully answered to 'resolved'. For more details look to FAQ's about Forum Usage. BTW I'm using Framework 3.5 and you ? My latest articles : Creating a Dockable Panel-Controlmanager Using C#, Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7
In that case, you should note that a line containing the word "class" will rarely (if ever?) be the first line in a C# class file. Rather, a line containing the word "using" will.
However, if you're only concerned about collecting classes into .cs files, give this a go:
Code:
int startbracket = 0;
int endbracket = 0;
List<string> classtext = new List<string>();
int fileno = 0;
foreach (string line in File.ReadAllLines("cricket.txt"))
{
classtext.Add(line);
if (line.ToLower().Contains(" class "))
{
//start of a class
startbracket = 0;
endbracket = 0;
classtext = new List<string>();
classtext.Add(line);
}
if (line.Trim() == "{")
startbracket++;
if (line.Trim() == "}")
endbracket++;
if (startbracket != 0 && startbracket == endbracket)
{
//end of a class.
File.WriteAllLines("class" + fileno + ".cs", classtext.ToArray());
fileno++;
startbracket = 0;
endbracket = 0;
classtext = new List<string>();
}
}
It's just something I put together since it's only 10 minutes until quittin' time
... but it might help you
And the only thing is....how would i be able to keep the class names as the file name?
instead of class1.cs
persontype.cs
and for the last "File.WriteAllLines", would it be possible to make them output to another directory other than the bin folder of the proejct your working on?
and for what you said bout the "using" thing... that I do not have to worry abvout but the only thing that might be a problem is that before each start of a class there are a set of attributes that the class uses that are in this form:
[System.CodeDom.
[System....]
[System....]
i need those to be in the .cs file per class as well so do you think I would be able to just use a regex somehow?
the code you gave me works perfectly for this and that code i have been working on might actually be able to satisfy the requirment for another part
Last edited by Code_Guru_Cricket; June 16th, 2010 at 10:33 AM.
Reason: clarrification on requirements
When I try that code...it only saves the very last instance of when it has "class" in the line as the file name.
i.e last line with class in it (it is the last class in file) is
public class SystemContact
so now the file name is called SystemContact.cs
it is basically just a copy of the original file
Would this mean its jsut not saving each "class" into its own file?
Attached is part of the file i have been using as my test file
this is what I have as of now....It will succesfully take every class and enum and output into its own seperate file now the only part I need to finish is to somehow get the [System.] attribute things along with the accompaying class
Code:
int startbracket = 0;
int endbracket = 0;
List<string> classtext = new List<string>();
var masterList = new List<List<String>>();
int fileno = 0;
string path = @"C:\Users\will.karavites\Desktop\Extracter_v1\Ucore.cs";
string path2 = @"C:\Users\will.karavites\Desktop\Extracter_v1\output\";
Regex enum1 = new Regex("^\\s{1,5}public enum", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled);
Regex regex = new Regex("^\\s{1,5}public partial", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Compiled);
Regex colonreg = new Regex("\\s:\\s",RegexOptions.IgnoreCase| RegexOptions.Multiline| RegexOptions.Compiled);
foreach (string line in File.ReadAllLines(path))
{
bool e1T = enum1.IsMatch(line);
bool regT = regex.IsMatch(line);
classtext.Add(line);
if (regT || e1T)
{
//start of a class
startbracket = 0;
endbracket = 0;
classtext = new List<string>();
classtext.Add(line);
}
if (line.Trim() == "{") { startbracket++; }
if (line.Trim() == "}") { endbracket++; }
if (startbracket != 0 && startbracket == endbracket)
{
//masterList.Add(classtext);
textBox1.Text = classtext[0];
//end of a class.
classtext.TrimExcess();
var greentea = classtext.ToArray();
string fName = colonreg.Replace(greentea[0], "_");
File.WriteAllLines(path2 + fName + ".cs", greentea);
fileno++;
startbracket = 0;
endbracket = 0;
classtext = new List<string>();
Last edited by Code_Guru_Cricket; June 17th, 2010 at 08:57 AM.
Reason: Put in test document
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.