C#:
Okay this seems freakishly easy, but all the help files and forums I've seen only show me how to do this with fixed lengths, etc.
I have a large string (~6.5MB) which I want to parse into an array of thousands of smaller strings (=1 line each). The splitting part seems easy, just seperate them at every instance of "\n". What I can't figure out is how to declare the array of a dynamic
number of strings. So far what I have is this:
internal static
void ArrayCreate(string fileText) {
string[] logEntry;
int[] logIndex, logIndexNext;
for (int tempIndex=1; tempIndex < (fileText.Length); tempIndex++) {
string[] logIndex =
new string[tempIndex];
int logIndex[tempIndex]=fileText.IndexOf("\n",tempIndex);
int logIndexNext[tempIndex] = fileText.IndexOf("\n",(logIndex[tempIndex]+1));
}
This seems to me as the way to do it. What am I doing wrong? For anyone interested, the project is a reader that will download and parse access.log files from a Yahoo-based webserver, then provide an arseload of information that will be dealt with later.
As will be more obvious to you than to me, I'm getting errors:
1. Syntax error, bad array declarator.
2. Array size cannot be specified in a variable declaration
So what am I doing wrong?
logEntry[] = arrays of strings that will contain an individual log entry
logIndex[] = Pointers for logEntry[]
logIndexNext[] = Pointer for the next entry (logEntry[] not done building yet)
tempIndex = temp pointer for current progress
-
-
The string.Split() method should do it for ya...
string info = "mark\nsmith\n123 csharp drive\ntoronto\ncanada";string[] arInfo = info.Split('\n');
-
Performance and memory usage wise you might be better of reading the log file with a StreamReader using ReadLine instead of reading the entire thing into one huge string and then splitting that. Put the string into a System.Collections.Specialized.StringCollection (or if you're using 2.0 you could use System.Collections.Generic.List<String>) as you read them.
-
Y'know, Sven, I tried that at first; but it seems that once it read in a few hundred thousand entries it froze up. I found this by adding a simple if-messagebox line. When I switched it to a ReadToEnd() call, it read the entire file in three seconds. Plus, I intend to have the file grow larger since it's only two weeks' worth of logs.
-
Beltira1968 wrote:
The string.Split() method should do it for ya...
string info = "mark\nsmith\n123 csharp drive\ntoronto\ncanada";string[] arInfo = info.Split('\n');
That did it, and nice and fast too. Thanks. -
SlackmasterK wrote:C#:
...
What I can't figure out is how to declare the array of a dynamic number of strings.
FYI (and after you've gotten your answer) you can't--arrays are fixed length.
-
Lists are the closest variable length equivalent to an Array, where you can get elements by index and such. There is no appropriate language feature in C#, you're stuck using the class library.
-
With .NET 2.0, you can achieve the same thing just with a single line of code:
String[] logs = System.IO.File.ReadAllLines("logs.txt");
PS: this implemention is quite simple, but it isn't performant just as Sven broken out above.
Sheva -
amotif wrote:FYI (and after you've gotten your answer) you can't--arrays are fixed length.
Strange, I was able to do it just fine:
string[] logEntry = Log.processLog(fileName).Split('\n');
// Log.processLog:
public static string processLog(string fileName) {
System.IO.StreamReader s = System.IO.File.OpenText(fileName);
string fileText = s.ReadToEnd(); // Parse local file into string
s.Close();
return fileText;}
The result (currently) is an array of about 28,000 strings. -
SlackmasterK wrote:

amotif wrote: FYI (and after you've gotten your answer) you can't--arrays are fixed length.
Strange, I was able to do it just fine:
string[] logEntry = Log.processLog(fileName).Split('\n');
Split creates a new array that just so happens to be the right size. You can't add more to it. It's funky like that. -
[dupe]
-
amotif wrote:

SlackmasterK wrote:C#:
...
What I can't figure out is how to declare the array of a dynamic number of strings.
FYI (and after you've gotten your answer) you can't--arrays are fixed length.
I suppose I could deconstruct your question a little differently.
a) Yes, you can declare a reference to an array of indescriminant length:
string[] a;
After all, C# is not Ada.
a = new string[0];
a = new string[1];
a = new string[1024*1024];
b) However, as pointed about above arrays are still fixed length.
Carry on.
-
As an off topic, The File.RealAllLines method is internally defined as follows:
public static string[] ReadAllLines(string path, Encoding encoding)
{
ArrayList list1 = new ArrayList();
using (StreamReader reader1 = new StreamReader(path, encoding))
{
string text1;
while ((text1 = reader1.ReadLine()) != null)
{
list1.Add(text1);
}
}
return (string[]) list1.ToArray(typeof(string));
}
Why not use List<String> instead of ArrayList, so that the cast operation can be crossed out in the return statement?
Sheva
-
Interesting.. This thread has proven most helpful thus far; ReadAllLines has multiplied the log parsing method by a factor of a few hundred. Not much for status updates in the process, but it's so fast they're not really necessary.
-
SlackmasterK wrote:So what am I doing wrong?
A question, am I not correct? In fact, a question that has been asked. Then why:
SlackmasterK wrote:If you have to ask, you're not ready to know yet.

-
SlackmasterK wrote:Y'know, Sven, I tried that at first; but it seems that once it read in a few hundred thousand entries it froze up. I found this by adding a simple if-messagebox line. When I switched it to a ReadToEnd() call, it read the entire file in three seconds. Plus, I intend to have the file grow larger since it's only two weeks' worth of logs.
SlackmasterK wrote:Interesting.. This thread has proven most helpful thus far; ReadAllLines has multiplied the log parsing method by a factor of a few hundred. Not much for status updates in the process, but it's so fast they're not really necessary.
FYI, ReadAllLines does exactly what I described earlier: it goes over the file line by line with a StreamReader.
In fact, according to Reflector this is the code for ReadAllLines:
public static string[] ReadAllLines(string path, Encoding encoding)
{
ArrayList list1 = new ArrayList();
using (StreamReader reader1 = new StreamReader(path, encoding))
{
string text1;
while ((text1 = reader1.ReadLine()) != null)
{
list1.Add(text1);
}
}
return (string[]) list1.ToArray(typeof(string));
}
Which is precisely what I described. I probably would've used a List<string> instead of an ArrayList, but that hardly matters in this case.
EDIT: Sorry, didn't see footballism's post. -
Khamul wrote:

SlackmasterK wrote: So what am I doing wrong?
A question, am I not correct? In fact, a question that has been asked. Then why:

SlackmasterK wrote: If you have to ask, you're not ready to know yet.

I rotate my captions sometimes. Unfortunately, the one I really want won't fit:
There is nothing more fearful than ignorance in action.
Think left and think right, think low and think high;
Oh the things you can think of, if only you try. -
footballism wrote:As an off topic, The File.RealAllLines method is internally defined as follows:
[snip]
Why not use List<String> instead of ArrayList, so that the cast operation can be crossed out in the return statement?
These are just guesses:
- There's no need to change the implementation of BCL methods just because there's another way to do it.
- Perhaps the performance or size implications aren't desirable.
Thread Closed
This thread is kinda stale and has been closed but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.