My application should read a C# code sample that is unindented, then indent the code programatically. The way I am doing it may not be correct but still could achieve partial results.
I could set white spaces when a { is found then continue with the same amount of space for rest of the lines being read. When another { is found again add spaces and continue with this new space for rest of lines. For that this is what I did:
private void btn_format_Click(object sender, EventArgs e)
{
string lineInfo = "";
string fl = "";
string ctab= char.ConvertFromUtf32(32)+char.ConvertFromUtf32(32)+char.ConvertFromUtf32(32);
foreach (string line in txt_codepage.Lines) // text_codepage is a textbox with code
{
if (line.Contains("{"))
{
string l = line.Replace("{", ctab+"{");
lineInfo = lineInfo + (l + "\n");
fl = fl + ctab;
ctab = ctab + ctab;
}
else
{
lineInfo = lineInfo + (char.ConvertFromUtf32(32)+fl+ line + "\n");
}
I could achieve the proper indentation that I want till here. Now when I find a } I should do the reverse process but unfortunately that is not possible with strings. The reverse process that I meant is this:
if (line.Contains("}"))
{
string l = line.Replace(ctab + "}", "}");
lineInfo = lineInfo + (l + "\n");
fl = fl - ctab;
ctab = ctab - ctab;
}
else
{
lineInfo = lineInfo - (char.ConvertFromUtf32(32) + fl + line + "\n");
}
}
MessageBox.Show(lineInfo.ToString());
I know the above part of the code is a complete blunder but let me know how to achieve it in correct way
If you want parse string, you should use StringBuilder instead string concatenations (concatenations is to slow). I wrote some code, to demonstrate how you can parse CS or other code. It is not a full example, just a basic concepts.
If you want learn more about parsers you can read Compilers: Principles, Techniques, and Tools.
public static string IndentCSharpCode(string code)
{
const string INDENT_STEP = " ";
if (string.IsNullOrWhiteSpace(code))
{
return code;
}
var result = new StringBuilder();
var indent = string.Empty;
var lineContent = false;
var stringDefinition = false;
for (var i = 0; i < code.Length; i++)
{
var ch = code[i];
if (ch == '"' && !stringDefinition)
{
result.Append(ch);
stringDefinition = true;
continue;
}
if (ch == '"' && stringDefinition)
{
result.Append(ch);
stringDefinition = false;
continue;
}
if (stringDefinition)
{
result.Append(ch);
continue;
}
if (ch == '{' && !stringDefinition)
{
if (lineContent)
{
result.AppendLine();
}
result.Append(indent).Append("{");
if (lineContent)
{
result.AppendLine();
}
indent += INDENT_STEP;
lineContent = false;
continue;
}
if (ch == '}' && !stringDefinition)
{
if (indent.Length != 0)
{
indent = indent.Substring(0, indent.Length - INDENT_STEP.Length);
}
if (lineContent)
{
result.AppendLine();
}
result.Append(indent).Append("}");
if (lineContent)
{
result.AppendLine();
}
lineContent = false;
continue;
}
if (ch == '\r')
{
continue;
}
if ((ch == ' ' || ch == '\t') && !lineContent)
{
continue;
}
if (ch == '\n')
{
lineContent = false;
result.AppendLine();
continue;
}
if (!lineContent)
{
result.Append(indent);
lineContent = true;
}
result.Append(ch);
}
return result.ToString();
}
You can go and check out codemaid, an open source VS add in for cleaning code
Remove all of the whitespace from the line using String.Trim() and then add just the tabs you want. Also, your code would be much more readable if you could avoid char.ConvertFromUtf32(32) - why write that instead of " " or ' '?
Related
I use the following as a parameter to the split function in C#:
private char[] delimiterComment = { '(', '{', '[', '\u201C' };
private char[] delimiterEndComment = { ')', '}', ']', '\u201D' };
It works on all the "brackets" but not the "curly double quotes". I don't understand why. Is it a bug in split, or a feature of the curly quote characters?
I have as an input string something like:
“this is a pre comment” then some vital info [there might be an embedded comment] and then some more vital info (then there is a post comment)
I wish to strip off the comments, but capture them in a structure, leaving a clean info string. It all worked beautifully with brackets, till I tried to add curly double quotes as additional delimiters...
(I am aware that embedded comments are being gathered as post comments deliberately)
The code I have written is as follows:
class CommentSplit
{
public bool split = false;
public bool error = false;
public string original = "";
public string remainder = "";
public string preComment = "";
public string postComment = "";
public CommentSplit(string inString, char[] startComment, char[] endComment, string[] ignoreStrings, string[] addStrings, bool usePre) // creator
{
if (inString == null)
return;
original = inString;
string[] starts = inString.Split(startComment);
if (starts.Length == 1)
{
remainder = inString;
return;
}
if (starts[0] != "")
remainder += starts[0].TrimEnd();
for (int i = 1; i < starts.Length; i++)
{
string[] ends = starts[i].Split(endComment);
if (ends.Length != 2) // more than one end comment for a start comment - BUT what about one start and one end comment
{
error = true;
return;
}
if (addStrings == null)
{
if (ignoreStrings == null)
{
if ((remainder == "") && usePre)
preComment += ends[0];
else
postComment += ends[0];
}
else
{
bool ignore = false;
for (int z = 0; z < ignoreStrings.Length; z++)
{
if (ends[0].ToLower() == ignoreStrings[z])
ignore = true;
}
if (!ignore) // was a comment but we might want to ignore it
{
if ((remainder == "") && usePre)
{
if (preComment != "")
preComment += " ";
preComment += ends[0];
}
else
{
if (postComment != "")
postComment += " ";
postComment += ends[0];
}
}
}
}
else
{
bool add = false;
for (int z = 0; z < addStrings.Length; z++)
{
if (ends[0].ToLower() == addStrings[z])
add = true;
}
if (add) // was a comment but want it in the remainder
{
if (remainder != "")
remainder += " ";
remainder += ends[0];
}
else
{
if (ignoreStrings == null)
{
if ((remainder == "") && usePre)
preComment += ends[0];
else
postComment += ends[0];
}
else
{
bool ignore = false;
for (int z = 0; z < ignoreStrings.Length; z++)
{
if (ends[0].ToLower() == ignoreStrings[z])
ignore = true;
}
if (!ignore) // was a comment but we might want to ignore it
{
if ((remainder == "") && usePre)
{
if (preComment != "")
preComment += " ";
preComment += ends[0];
}
else
{
if (postComment != "")
postComment += " ";
postComment += ends[0];
}
}
}
}
}
if (remainder != "")
remainder += " ";
remainder += ends[1].Trim();
}
split = true;
} // CommentSplit
}
I should note that I am a retired C programmer dabbling in C#, so my style may not be OOP efficient. I did originally include straight (non curly) double quotes, but they are not important, and indeed stuff things up as there is not an pre and post delimiter version of them.
Just Put double quote between single quote without using escape character :
private char[] delimiterComment = { '(', '{', '[', '\u201C', '"' };
private char[] delimiterEndComment = { ')', '}', ']', '\u201D', '"' };
Input :
string s = "abc(121), {12}, \" HI \"";
Console.WriteLine(string.Join(Environment.NewLine,(s.Split(delimiterComment)).Select(s=> s)));
Output :
abc
121),
12},
HI
So you want to cut off comments, e.g.
123 (456 [789) abc ] -> 123 abc ]
In this case you can try a simple loop:
//TODO: I suggest combining starts and ends into array of pairs, e.g.
// KeyValuePair<string,string>[]
private static string CutOffComments(string source, char[] starts, char[] ends) {
if (string.IsNullOrEmpty(source))
return source;
StringBuilder sb = new StringBuilder(source.Length);
int commentIndex = -1;
foreach (var c in source) {
if (commentIndex >= 0) { // within a comment, looking for its end
if (c == ends[commentIndex])
commentIndex = -1;
}
else { // out of comment, do we starting a new one?
commentIndex = Array.IndexOf(starts, c);
if (commentIndex < 0)
sb.Append(c);
}
}
//TODO:
// if (commentIndex >= 0) // dungling comment, e.g. 123[456
return sb.ToString();
}
Usage:
string source = "123[456]789";
// 123789
string result = CutOffComments(source, delimiterComment, delimiterEndComment);
Its something else in your code as this small verifiable example works fine:
char[] delimiterComment = { '(', '{', '[', '\u201C', '\u201D', '"', '“', '”', '}', ']', ')' };
string stringWithComment = "this has a “COMMENT” yeah really";
var result = stringWithComment.Split(delimiterComment);
//Output:
//result[0] = "this has a "
//result[1] = "COMMENT"
//result[2] = " yeah really"
Below is my code:
string ckeywords = File.ReadAllText("E:\\ckeywords.csv");
string[] clines = File.ReadAllLines("E:\\cprogram\\cpro\\bubblesort.c");
string letters="";
foreach(string line in clines)
{
char[] c = line.ToCharArray();
foreach(char i in c)
{
if (i == '/' || i == '"')
{
break;
}
else
{
letters = letters + i;
}
}
}
letters = Regex.Replace(letters, #"[^a-zA-Z ]+", " ");
List<string> listofc = letters.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();
List<string> listofcsv = ckeywords.Split(new char[] { ',', '\t', '\n', ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(p => p.Trim()).ToList();
List<string> Commonlist = listofcsv.Intersect(listofc).ToList();
With this if condition, I am able to ignore reading contents of single line comment and contents between ("").
I need to ignore reading contents of multi line comments. Which condition should I use?
Suppose my .c file is having this line of comment so with above code I don't know how to start iterating from /* to */ and to ignore the contents in between.
/*printf("Sorted list in ascending order:\n");
for ( c = 0 ; c < n ; c++ )
printf("%d\n", array[c]);*/
I successfully solved my problem now I can ignore reading contents of /* */ in a simpler way without using Regular Expression.
Here is my code:
string[] clines = File.ReadAllLines("E:\\cprogram\\cpro\\bubblesort.c");
List<string> list = new List<string>();
int startIndexofcomm, endIndexofcomm;
for (int i = 0; i < clines.Length ; i++ )
{
if (clines[i].Contains(#"/*"))
{
startIndexofcomm = clines[i].IndexOf(#"/*");
list.Add(clines[i].Substring(0, startIndexofcomm));
while(!(clines[i].Contains(#"*/")))
{
i++;
}
endIndexofcomm = clines[i].IndexOf(#"*/");
list.Add(clines[i].Substring(endIndexofcomm+2));
continue;
}
list.Add(clines[i]);
}
Here is code that naively does the following:
It strips out any multi-line comments starting with /* and ending with */, even if there are newlines between the two.
It strips out any single-line comments starting with // and ending at the end of the line
It does not strip out any comments like the above if they're within a string that starts with " and ends with a ".
LINQPad code:
void Main()
{
var code = File.ReadAllText(#"d:\temp\test.c");
code.Dump("input");
bool inString = false;
bool inSingleLineComment = false;
bool inMultiLineComment = false;
var output = new StringBuilder();
int index = 0;
while (index < code.Length)
{
// First deal with single line comments: // xyz
if (inSingleLineComment)
{
if (code[index] == '\n' || code[index] == '\r')
{
inSingleLineComment = false;
output.Append(code[index]);
index++;
}
else
index++;
continue;
}
// Then multi-line comments: /* ... */
if (inMultiLineComment)
{
if (code[index] == '*' && index + 1 < code.Length && code[index + 1] == '/')
{
inMultiLineComment = false;
index += 2;
}
else
index++;
continue;
}
// Then deal with strings
if (inString)
{
output.Append(code[index]);
if (code[index] == '"')
inString = false;
index++;
continue;
}
// If we get here we're not in a string or in a comment
if (code[index] == '"')
{
// We found the start of a string
output.Append(code[index]);
inString = true;
index++;
}
else if (code[index] == '/' && index + 1 < code.Length && code[index + 1] == '/')
{
// We found the start of a single line comment
inSingleLineComment = true;
index++;
}
else if (code[index] == '/' && index + 1 < code.Length && code[index + 1] == '*')
{
// We found the start of a multi line comment
inMultiLineComment = true;
index++;
}
else
{
// Just another character
output.Append(code[index]);
index++;
}
}
output.ToString().Dump("output");
}
Sample input:
This should be included // This should not
This should also be included /* while this
should not */ but this should again be included.
Any comments in " /* strings */ " should be included as well.
This goes for "// single line comments" as well.
Sample output (note that there are some spaces at the end of some of the lines below that aren't visible):
This should be included
This should also be included but this should again be included.
Any comments in " /* strings */ " should be included as well.
This goes for "// single line comments" as well.
How can I write a function which given an input string, passes back the acronym for the string using only If/Then/Else, simple String functions, and Looping syntax (not use the Split( ) function or its equivalent)?
String s_input, s_acronym
s_input = "Mothers against drunk driving"
s_acronym = f_get_acronym(s_input)
print "acronym = " + s_acronym
/* acronym = MADD */
My code is here. just looking to see if I could get better solution
static string f_get_acronym(string s_input)
{
string s_acronym = "";
for (int i = 0; i < s_input.Length; i++)
{
if (i == 0 && s_input[i].ToString() != " ")
{
s_acronym += s_input[i];
continue;
}
if (s_input[i - 1].ToString() == " " && s_input[i].ToString() != " ")
{
s_acronym += s_input[i];
}
}
return s_acronym.ToUpper();
}
Regex is the way to go in C#. I know you only wanted simple functions, but I want to put this here for any further readers who shall be directed on the right path. ;)
var regex = new Regex(#"(?:\s*(?<first>\w))\w+");
var matches = regex.Matches("Mother against druck driving");
foreach (Match match in matches)
{
Console.Write(match.Groups["first"].Value);
}
private static string f_get_acronym(string s_input)
{
if (string.IsNullOrWhiteSpace(s_input))
return string.Empty;
string accr = string.Empty;
accr += s_input[0];
while (s_input.Length > 0)
{
int index = s_input.IndexOf(' ');
if (index > 0)
{
s_input = s_input.Substring(index + 1);
if (s_input.Length == 0)
break;
accr += s_input[0];
}
else
{
break;
}
}
return accr.ToUpper();
}
Keep it simple:
public static string Acronym(string input)
{
string result = string.Empty;
char last = ' ';
foreach(var c in input)
{
if(char.IsWhiteSpace(last))
{
result += c;
}
last = c;
}
return result.ToUpper();
}
Best practice says you should use a StringBuilder when adding to a string in a loop though. Don't know how long your acronyms are going to be.
Your best way to do so would be to set up a loop to loop over every letter. If it is the first letter in the string, OR the first letter after a space, add that letter to a temp string, which is returned at the end.
eg (basic c++)
string toAcronym(string sentence)
{
string acronym = "";
bool wasSpace = true;
for (int i = 0; i < sentence.length(); i++)
{
if (wasSpace == true)
{
if (sentence[i] != ' ')
{
wasSpace = false;
acronym += toupper(sentence[i]);
}
else
{
wasSpace = true;
}
}
else if (sentence[i] == ' ')
{
wasSpace = true;
}
}
return acronym;
}
This could be further improved by checking to make sure the letter to add to the acronym is a letter, and not a number / symbol. OR...
If it is the first letter in the string, add it to the acronym. Then, run a loop for "find next of" a space. Then, add the next character. Continuously loop the "find next of" space until it returns null / eof / end of string, then return.
On my local machine, this:
Trace.Warn("\u012b");
Outputs this (which is wrong):
ī
Yet, on another machine, (eg. here: http://www.volatileread.com/UtilityLibrary/SnippetCompiler):
Console.WriteLine("\u012b");
Outputs:
i
What's happening?
EDIT: I'm using this function from here: Any libraries to convert number Pinyin to Pinyin with tone markings?
public static string ConvertNumericalPinYinToAccented(string input)
{
Dictionary<int, string> PinyinToneMark = new Dictionary<int, string>
{
{0, "aoeiuv\u00fc"},
{1, "\u0101\u014d\u0113\u012b\u016b\u01d6\u01d6"},
{2, "\u00e1\u00f3\u00e9\u00ed\u00fa\u01d8\u01d8"},
{3, "\u01ce\u01d2\u011b\u01d0\u01d4\u01da\u01da"},
{4, "\u00e0\u00f2\u00e8\u00ec\u00f9\u01dc\u01dc"}
};
string[] words = input.Split(' ');
string accented = "";
string t = "";
foreach (string pinyin in words)
{
foreach (char c in pinyin)
{
if (c >= 'a' && c <= 'z')
{
t += c;
}
else if (c == ':')
{
if (t[t.Length - 1] == 'u')
{
t = t.Substring(0, t.Length - 2) + "\u00fc";
}
}
else
{
if (c >= '0' && c <= '5')
{
int tone = (int)Char.GetNumericValue(c) % 5;
if (tone != 0)
{
Match match = Regex.Match(t, "[aoeiuv\u00fc]+");
if (!match.Success)
{
t += c;
}
else if (match.Groups[0].Length == 1)
{
t = t.Substring(0, match.Groups[0].Index) +
PinyinToneMark[tone][PinyinToneMark[0].IndexOf(match.Groups[0].Value[0])]
+ t.Substring(match.Groups[0].Index + match.Groups[0].Length);
}
else
{
if (t.Contains("a"))
{
t = t.Replace("a", PinyinToneMark[tone][0].ToString());
}
else if (t.Contains("o"))
{
t = t.Replace("o", PinyinToneMark[tone][1].ToString());
}
else if (t.Contains("e"))
{
t = t.Replace("e", PinyinToneMark[tone][2].ToString());
}
else if (t.Contains("ui"))
{
t = t.Replace("i", PinyinToneMark[tone][3].ToString());
}
else if (t.Contains("iu"))
{
t = t.Replace("u", PinyinToneMark[tone][4].ToString());
}
else
{
t += "!";
}
}
}
}
accented += t;
t = "";
}
}
accented += t + " ";
}
accented = accented.TrimEnd();
return accented;
}
Eg.: ConvertNumericalPinYinToAccented("ba2itia1n");
Working version: http://volatileread.com/utilitylibrary/snippetcompiler?id=22734
On this link there is an answer that might be usefull to you.
https://superuser.com/questions/412986/unicode-support-between-different-os-and-browsers
The unicode interpretation depends on the Browser you use and the OS that the server is running on. Knowing that, it is normal that a small difference appears.
Hi all i am having a list box on my Form which will display all the .txt files from the directory C:. This list box selection mode is set to MultiExtended.
My condition to check whether the file is valid or not will be checked using the condition as each and every line content of the selected file should be *94*. If this one satisifes then only it is said to be a valid file. I have written a code for this too but as i am checking in the loop and at a time i can only read one file content this was working fine. But i have to check initially all the selected files matches the condition or not if ok then i have to do the remaining code if not i would like to display error
My code on Button Click
private void btnMerge_Click(object sender, EventArgs e)
{
if (lstACH.SelectedIndices.Count == 1)
{
MessageBox.Show("Select 2 Files To Merge");
}
else
{
for (i = 0; i < lstACH.SelectedItems.Count; i++)
{
strFile = lstACH.SelectedItems[i].ToString();
lines = File.ReadAllLines(strFile);
if (LinesHaveCorrectLength(lines, 94)) // Here i am checking but at a tym i am checking one file only i have to check for all and if ok then the remaining code has to be executed
{
if (i == 0)
{
Stream myStream;
SaveFileDialog saveFileDialog1 = new SaveFileDialog();
saveFileDialog1.InitialDirectory = #"C:\";
saveFileDialog1.DefaultExt = "txt";
saveFileDialog1.Filter = "(*.txt)|*.txt";
saveFileDialog1.FilterIndex = 2;
saveFileDialog1.RestoreDirectory = true;
saveFileDialog1.ValidateNames = true;
if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
Append.FileName = saveFileDialog1.FileName;
if (Append.FileName.Contains(" \\/:*?<>|"))
{
MessageBox.Show("File name should not contain \\/:*?<>|", "", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
if ((myStream = saveFileDialog1.OpenFile()) != null)
{
Append.FileName = saveFileDialog1.FileName;
myStream.Close();
}
}
}
}
using (StreamWriter sw = new StreamWriter(Append.FileName, true))
{
using (StreamReader srBatch = new StreamReader(strFile))
{
while (srBatch.Peek() >= 0)
{
strReadLine = srBatch.ReadLine();
if (strReadLine.StartsWith("1"))
{
if (i == 0)
{
strFileHeader = strReadLine;
sw.WriteLine(strFileHeader);
}
}
if (strReadLine.StartsWith("5"))
{
strBtchHeader = strReadLine;
if (i == 0)
{
Btchno = Convert.ToInt32(strReadLine.Substring(87, 7));
BatchCnt = Convert.ToInt16(Btchno);
}
if (i > 0)
{
BatchCnt++;
strBtchHeader = strBtchHeader.Substring(0, 87) + Convert.ToString(BatchCnt.ToString().PadLeft(7, (char)48));
}
sw.WriteLine(strBtchHeader);
}
if (strReadLine.StartsWith("6"))
{
strEntryDetail = strReadLine;
if (i == 0)
{
strTraceNo = strEntryDetail.Substring(87, 7);
EntryCount = Convert.ToInt16(strTraceNo);
}
if (i > 0)
{
EntryCount++;
strEntryDetail = strEntryDetail.Substring(0, 87) + EntryCount.ToString().PadLeft(7, (char)48);
}
sw.WriteLine(strEntryDetail);
}
if (strReadLine.StartsWith("8"))
{
strBtchCntrl = strReadLine;
if (i > 0)
{
//btchEntry++;
strBtchCntrl = strBtchCntrl.Substring(0, 87) + BatchCnt.ToString().PadLeft(7, (char)48);
}
sw.WriteLine(strBtchCntrl);
}
if (strReadLine.StartsWith("9"))
{
strFileCntrl = strReadLine;
strBtchCnt = strReadLine.Substring(1, 6);
strEntrycnt = strReadLine.Substring(13, 8);
strEntryHash = strReadLine.Substring(21, 10);
strDebitAmnt = strReadLine.Substring(31, 12);
strCreditAmnt = strReadLine.Substring(43, 12);
BtchCnt += Convert.ToDouble(strBtchCnt);
Entrycnt += Convert.ToDouble(strEntrycnt);
EntryHash += Convert.ToDouble(strEntryHash);
DebitAmnt += Convert.ToDouble(strDebitAmnt);
CreditAmnt += Convert.ToDouble(strCreditAmnt);
if (i == lstACH.SelectedItems.Count - 1)
{
strFileCntrl = strFileCntrl.Substring(0, 1) + BtchCnt.ToString().PadLeft(6, (char)48) + strFileCntrl.Substring(7, (strFileCntrl.Length - 7));
strFileCntrl = strFileCntrl.Substring(0, 13) + Entrycnt.ToString().PadLeft(8, (char)48) + strFileCntrl.Substring(21, (strFileCntrl.Length - 21));
strFileCntrl = strFileCntrl.Substring(0, 21) + EntryHash.ToString().PadLeft(10, (char)48) + strFileCntrl.Substring(31, (strFileCntrl.Length - 31));
strFileCntrl = strFileCntrl.Substring(0, 31) + DebitAmnt.ToString().PadLeft(12, (char)48) + strFileCntrl.Substring(43, (strFileCntrl.Length - 43));
strFileCntrl = strFileCntrl.Substring(0, 43) + CreditAmnt.ToString().PadLeft(12, (char)48) + strFileCntrl.Substring(55, (strFileCntrl.Length - 55));
sw.WriteLine(strFileCntrl);
}
}
}
}
}
if (i == lstACH.SelectedItems.Count - 1)
{
MessageBox.Show("File Has Been Merged Successfully");
this.Close();
}
}
else
{
MessageBox.Show("One of the Selected File is not a Valid ACH File");
break;
}
}
}
}
Checking for Each and every line Length
private static bool LinesHaveCorrectLength(string[] lines, int expectedLineLength)
{
foreach (string item in lines)
{
if (item.Length != expectedLineLength)
{
return false;
}
}
return true;
}
Just check them all first - and if all good, THEN begin merge.
if (lstACH.SelectedIndices.Count != 2)
{
MessageBox.Show("Select 2 Files To Merge");
return;
}
foreach (String fileName in lstACH.SelectedItems)
{
if( LinesHaveCorrectLength( File.ReadAllLines(fileName), 94 ) == false )
{
MessageBox.Show("File: " + fileName + " has an incorrect line length");
return;
}
}
// Now process them all again to merge:
foreach(String fileName in lstACH.SelectedItems)
{
// ... do merge logic
}
Ok according to your comment it looks like First you want both files to be validated. if that is the case then:
(There could be many ways , this is one of them)
First define a Function to do the checking for all files:
public bool AreFilesValid(ListBox.SelectedObjectCollection filenames)
{
int count = filenames.Count;
bool valid = false;
for(int i=0;i<count;i++)
{
string strFile = filenames[i].ToString();
string[] lines = File.ReadAllLines(strFile);
if(LinesHaveCorrectLength(lines, 94)) { valid=true; }
else { valid = false; }
}
return valid;
}
Then call it in your if condition, i.e just change following lines:
...
strFile = lstACH.SelectedItems[i].ToString();
lines = File.ReadAllLines(strFile);
if (LinesHaveCorrectLength(lines, 94))
{
...
To only this:
...
if (AreFilesValid(lstACH.SelectedItems))
{
...
You have already got your else statement down the code to catch when this if condition fails.