user2948119
user2948119

Reputation: 9

How to format a string multiple times with different integers?

So here's my problem, basically I'm reading the last few lines after a keyword ('#Footer' in my case) of a number of datafiles and only extracting relevant data, I'm able to extract the end of a file, but have an issue when reading multiple ones,

Say I've got some example files, 'testfile00', 'testfile21', 'testfile 10' etc

Keep in mind I'm not particularly experienced in any sort of programming, how would I go about reading these files and extracting the data from them?

I've got the following code so far;

static void Main(string[] args)
{
    try
    {
        for (int i = 0; i < 3; i++)
        {

                string str1 = @"C:\Users\XXXXX\Desktop\testfile";
                string str2 = i.ToString();
                string str3 = ".datafile";

                string final = str1 + str2 + str2 + str3;


                var lines = File.ReadLines(final)
                            .SkipWhile(line => !line.Contains("#Footer"))
                            .Skip(1)
                            .ToList();

                Console.WriteLine(String.Join(Environment.NewLine, lines));


        }
    }
    catch (Exception e)
    {
        Console.WriteLine("The file could not be read:");
        Console.WriteLine(e.Message);
        Console.Read();
    }
}

I know this is wrong using the 'str2 + str2', the results I get will only read the files, 'testfile00', 'testfile11' and 'testfile22', this is where I'm not sure how to correct this to get the files with 01, 12, 20 etc. any ideas?

Thanks

Upvotes: 0

Views: 136

Answers (2)

Rune FS
Rune FS

Reputation: 21742

You could use a nested loop

try
{
    string str1 = @"C:\Users\XXXXX\Desktop\testfile";
    string str3 = ".datafile";

    for (int i = 0; i < 3; i++)
    {
        for(int j = 0; j< 3; j++){               

            string final = str1 + i+ j + str3;


            var lines = File.ReadLines(final)
                        .SkipWhile(line => !line.Contains("#Footer"))
                        .Skip(1)
                        .ToList();

            Console.WriteLine(String.Join(Environment.NewLine, lines));
        }

    }
}
catch (Exception e)
{
    Console.WriteLine("The file could not be read:");
    Console.WriteLine(e.Message);
    Console.Read();
}

However you might want to make sure the file exist before you try to read it and you also might wish to make it more declarative since that's usually easier to read. (When to get the hang of the syntax). The human mind is a lot better at reading/understanding something that's sequential than it is executing a loop

var path = @"C:\Users\XXXXX\Desktop\testfile";
var ext  = ".datafile";
var range = Enumerable.Range(0,3);
var filePaths = 
             from i in range
             from j in range
             let file = path + i + j+ ext
             where File.Exists(file)
             select File.ReadLines(f)
                        .SkipWhile(line => !line.Contains("#Footer"))
                        .Skip(1);
try{
   Console.WriteLine(String.Join(Environment.NewLine,filePaths.SelectMany(f => f));
} catch (Exception e)
{
    Console.WriteLine("The file could not be read:");
    Console.WriteLine(e.Message);
    Console.Read();
}

EDIT It would seem from your comment that the files your are talking about are not named in a consequtive way in that case it's probably better to something similar to Michaels answer

Essentially you'd need to replace the first 3 lines from the LINQ statement above above

      var filePaths = 
             //This will go through all files in the directory but can be narrowed
             //down if needed ie if not all files should be parsed
             from i in Directory.GetFiles(path)
             //You don't need to test if the files exist any more
             select File.ReadLines(f)
                        .SkipWhile(line => !line.Contains("#Footer"))
                        .Skip(1);

Upvotes: 0

Mike Perrenoud
Mike Perrenoud

Reputation: 67898

I think an easier approach would be:

foreach (var file in Directory.GetFiles(yourPath, "*.datafile"))
{
    var lines = File.ReadLines(file)
                    .SkipWhile(line => !line.Contains("#Footer"))
                    .Skip(1)
                    .ToList();

    Console.WriteLine(String.Join(Environment.NewLine, lines));
}

where yourPath in this case is C:\Users\XXXXX\Desktop\

Upvotes: 2

Related Questions