2

I want to read integers from a file for example I want to read a vector from a file like this (0,0,0) and I want to save each parameter, x=0 y=0 z=0 how can I split string and save the integer. I have a reading program that reads integers but the problem comes when I have a double digit integer, the program is not reading right values. My text file is something like this:

:Cube.Attach(100,0,5);
:Tree.Attach(10,0,50);
:Plane.Attach(0,0,0);
:Terrain.Attach(0,0,0);
Cœur
  • 37,241
  • 25
  • 195
  • 267
anthraxa
  • 35
  • 12
  • Either use regular expressions or a simple file format, where each vector is in a new line and the numbers are separated by whitespaces, this way you can simply use `string.split`. Either way, for more complex data you should not be using txt files anyway. You were better off using XML. – nyro_0 May 30 '16 at 09:43
  • *"the problem comes when i have a double diggit integer"* - which problem comes? Exception? Something is not working? Can you show your code, give some sample input and show produced and expected output? – Sinatr May 30 '16 at 09:45
  • This is the format i have to use, as my program is also looking if the method exists Attach in this example. I will try with regular expressions then. Thank you for your answer – anthraxa May 30 '16 at 09:46
  • @Sinatr i just want to read x value like this that the program reads integer between ( and , and then the next integer y between two , , and then z integer between , and ) – anthraxa May 30 '16 at 09:47
  • Parse your line with a regex like `(\d+,\d+,\d+)` and split with the comma `,` – Quentin Roger May 30 '16 at 09:50
  • Show how you reading it now. Or just search for something like [this](http://stackoverflow.com/q/2235683/1997232) (you have to be creative when searching). – Sinatr May 30 '16 at 09:50
  • @QuentinRoger this seems very logical as we parse into 3 integers, could you maybe provide me an example of this or would something like this work: Match match = Regex.match(line, @":Cube.Attach(\d+,\d+,\d+)\$"); – anthraxa May 30 '16 at 10:00

1 Answers1

3

You can try using regular expressions, something like this:

  // Possible operations
  Dictionaty<String, Func<int, int, int, MyObject>> operations =
    new Dictionaty<String, Func<int, int, int, MyObject>>() {
      {"Cube.Attach", (x, y, z) => Cube.Attach(x, y, z);},
      {"Tree.Attach", (x, y, z) => Tree.Attach(x, y, z);},
      {"Plain.Attach", (x, y, z) => Plain.Attach(x, y, z);},
      {"Terrain.Attach", (x, y, z) => Terrain.Attach(x, y, z);},
      ... 
    }
  ...

  // Please, notice spaces and minus sign (-125)
  String source = ":Cube.Attach(100, 18, -125);";

  ...

  String pattern = @"^:(?<Func>[A-Za-z.]+)\((?<Args>.+)\);$";

  Match match = Regex.Match(source, pattern);

  if (match.Success) {
    // Operation name - "Cube.Attach" 
    // Comment it out if you don't want it 
    String func = match.Groups["Func"].Value;

    // Operation arguments - [100, 18, -125]
    int[] args = match.Groups["Args"].Value
      .Split(',')
      .Select(item => int.Parse(item, CultureInfo.InvariantCulture))
      .ToArray();

    // Let's find out proper operation in the dictionary and perform it
    // ... or comment it out if you don't want perform the operation here
    operations[func](args[0], args[1], args[2]); 
  }

In case you want to split "(0,0,0)" you have no need in regular expressions, since Split and Trim are enough:

  String source = "(100, 18, -125)";

  // [100, 18, -125] 
  int[] args = source
    .Trim('(', ')')
    .Split(',')
    .Select(item => int.Parse(item, CultureInfo.InvariantCulture)) 
    .ToArray();

  // finally, if you need it
  int x = args[0];
  int y = args[1];
  int z = args[2];
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
  • Thanks for your answer but unofrtunately i only need to parse the integers from characters, beacuse i have a working program on this and this is the only problem i need to solve and i think regex is the right answer for this. – anthraxa May 30 '16 at 10:06
  • @anthraxa: if you want to parse just for integers e.g. for `"(100, 18, -125)"` you want to have `[100, 18, -125]` regular expressions are overshoot, and it can be done with just `Split` (see my edit) – Dmitry Bychenko May 30 '16 at 10:13