Aa Yy
Aa Yy

Reputation: 1742

C# - Getting multiple values with a single key, from a text file

I store multiple values that shares a single key on a text file. The text file looks like that:

Brightness 36 , Manual
BacklightCompensation 3 , Manual
ColorEnable 0 , None
Contrast 16 , Manual
Gain 5 , Manual
Gamma 122 , Manual
Hue 0 , Manual
Saturation 100 , Manual
Sharpness 2 , Manual
WhiteBalance 5450 , Auto

Now I want to store the int value & string value of each key (Brightness, for example).

New to C# and could'nt find something that worked yet.

Thanks

Upvotes: 1

Views: 634

Answers (2)

Drag and Drop
Drag and Drop

Reputation: 2734

With a regex and a little bit of linq you can do many things.
Here I assume you Know How to read a Text file.

Pros: If the file is not perfect, the reg exp will just ignore the misformatted line, and won't throw error.

Here is a hardcode version of your file, note that a \r will appears because of it. Depending on the way you read you file but it should not be the case with a File.ReadLines()

string input =
@"Brightness 36 , Manual
BacklightCompensation 3 , Manual
ColorEnable 0 , None
Contrast 16 , Manual
Gain 5 , Manual
Gamma 122 , Manual
Hue 0 , Manual
Saturation 100 , Manual
Sharpness 2 , Manual
WhiteBalance 5450 , Auto";

string regEx = @"(.*) (\d+) , (.*)";

var RegexMatch = Regex.Matches(input, regEx).Cast<Match>();

var outputlist = RegexMatch.Select(x => new { setting = x.Groups[1].Value
                                              , value = x.Groups[2].Value
                                              , mode  = x.Groups[3].Value }); 

Regex explanation:/(.*) (\d+) , (.*)/g

1st Capturing Group (.*)
.* matches any character (except for line terminators)
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
matches the character literally (case sensitive)

2nd Capturing Group (\d+)
\d+ matches a digit (equal to [0-9])
+ Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
, matches the characters , literally (case sensitive)

3rd Capturing Group (.*)
.* matches any character (except for line terminators)
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)


Disclamer:

Never trust an input! Even if it's a file some other program did, or send by a customer.

From my experience, you have then two ways of handeling bad format:
Read line by line, and register every bad line.
or Ignore them. You don't fit , you don't sit!

And don't tell your self it won't happend, it will!

Upvotes: 1

Tim Schmelter
Tim Schmelter

Reputation: 460098

I'd recommend to use custom types to store these settings like these:

public enum DisplaySettingType
{
    Manual, Auto, None
}

public class DisplaySetting
{
    public string Name { get; set; }
    public decimal Value { get; set; }
    public DisplaySettingType Type { get; set; }
}

Then you could use following LINQ query using string.Split to get all settings:

decimal value = 0;
DisplaySettingType type = DisplaySettingType.None;

IEnumerable<DisplaySetting> settings = File.ReadLines(path)
    .Select(l => l.Trim().Split(new[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries))
    .Where(arr => arr.Length >= 3 && decimal.TryParse(arr[1], out value) && Enum.TryParse(arr[2], out type))
    .Select(arr => new DisplaySetting { Name = arr[0], Value = value, Type = type });

Upvotes: 2

Related Questions