C# 用C语言从文本文件中读取多维变量#

C# 用C语言从文本文件中读取多维变量#,c#,file,text,C#,File,Text,我正在尝试在C#(Windows窗体应用程序,Visual Studio)中创建一个GUI,用于从文本文件读取和写入某些变量。我对GUI本身没有问题,但我需要一个函数,可以读取(并最终写入)文本文件,识别变量并将其放入内部变量或直接放入GUI控件中。文本文件看起来像这样(但要长得多): 我有一个C代码可以读取文本文件,但它太长了。我的印象是,用一段相对较短的C#代码就可以优雅地完成这项工作。我已经试着按照建议使用字典,但是我的文本文件的格式太复杂了。。。除非某位大师知道一些可以帮助我的技巧 欢迎

我正在尝试在C#(Windows窗体应用程序,Visual Studio)中创建一个GUI,用于从文本文件读取和写入某些变量。我对GUI本身没有问题,但我需要一个函数,可以读取(并最终写入)文本文件,识别变量并将其放入内部变量或直接放入GUI控件中。文本文件看起来像这样(但要长得多):

我有一个C代码可以读取文本文件,但它太长了。我的印象是,用一段相对较短的C#代码就可以优雅地完成这项工作。我已经试着按照建议使用字典,但是我的文本文件的格式太复杂了。。。除非某位大师知道一些可以帮助我的技巧

欢迎你的建议。样本代码将不胜感激

以下内容定义了文本文件的格式:

  • 所有变量都以
    /YD/
    开头
  • /*
    */
    之间的文本是注释(无需阅读)
  • 分隔符可以是空格或制表符,在变量和值之间可以有一个或多个分隔符。也可以有空行
  • 有时每行有多个变量
  • 有时变量及其值在不同的行中
  • 有些变量是单值变量,有些是一维、二维或三维变量
  • 格式为xxxxxx的变量(不一定是固定数量的字符)后面跟着它的单个值
  • 形式为x1xxxxx的变量为1-D。这些变量后面跟着一个 整数,表示变量的大小,后跟 变量的值(例如变量
    /YD/YDPE/D1PEFR 3 0.7 0.75.5
    是一个一维变量,有三个值:0.7、0.75和0.5)
  • 格式为x2xxxxx的变量是二维的。这些变量后面首先是一个数字,告诉您如何读取变量,然后是变量的大小(2个数字),然后是变量的实际值。例如,变量
    /YD/YDPM/I2PMSET 21 3 2 1 3 0 1 0 1
    是一个二维变量,其中数字21表示首先读取更改“x”坐标,然后读取更改“y”坐标(12表示首先读取更改“y”然后更改“x”),接下来的数字
    3
    2
    表示大小为[3,2],以下6个数字是变量的值,顺序为
    (x1y1、x2y1、x3y1、x1y2、x2y2、x3y2)
  • 最后,x3xxxx形式的变量是3-D。这些变量后面是一个数字,告诉您如何读取它,然后是大小(3个数字),然后是值。例如,变量
    /YD/YDPN/D3PNFAC 231 2 3 4…
    是三维的,首先读“x”,然后读“z”,然后读“y”,大小是[2,3,4]。然后按照
    (x1y1z1、x2y1z1、x1y1z2、x2y1z2、x1y1z3、x2y1z3、x1y1z4、x2y1z4、x1y2z1、x2y2z1等)的顺序读取这些值

    • Mu建议重新构造文件的构建方式。这样,您就可以使用XML结构,并使所有代码更易于阅读

      看看:(
      System.Xml.Linq

      以下是您可以做的一个示例:

      <Root>
          <Controls>
              <Control/>
              ...
          </Controls>
          <Properties>
              <Property/>
              ...
          </Properties>
      </Root>
      

      要获取变量,请查看类。更具体地看一下
      Split
      Replace
      Trim
      方法。

      我认为C中的任何东西都不会神奇地为你做这件事,但为了避免我想象中你在C中遇到的意大利面代码,我会将它分解成一些类,每个类负责给定的变量类型。抱歉,这有点假代码,但我希望能有所帮助

      首先是基类:

      public abstract class DataValue {
          public string Category { get; protected set; } // value after /YD
          public string Name { get; protected set; } // value after /YD/XXX/
          public int DimensionCount { get; protected set; } // number of dimensions
          public int[] Dimensions { get; protected set; } // The size of each dimension
      
          protected void ParseHeader(string header) {
              // Split of the header into the Category/Name and set it
          }
      
          public virtual void ReadValue(string header, StreamReader reader) {
              ParseHeader(header);
          }
      }
      
      然后为每个变量类型创建一个类:

      public class ScalarValue: DataValue {
          public ScalarValue() {
              DimensionCount = 1;
              Dimensions = new [] { 1 };
          }
      
          public override void ReadValues(string header, StreamReader reader) {
              base.ReadValues(header, reader);
      
              // Do custom logic for reading a scalar here.
          }
      }
      
      您可以为每个主要类型创建这样的类。他们各自负责自己的阅读逻辑。您需要一个主解析器循环来查找变量、创建对象并分派它们:

      public static List<DataValue> ParseDataFile(string filePath) {
          var reader = new StreamReader(filePath);
      
          var values = new List<DataValue>();
          var variableHeader = FindNextVariable(reader);
      
          while(!string.IsNullOrEmpty(variableHeader)) {
              DataValue v;
      
              switch(FindVariableType(variableHeader)) {
                  case Scalar:
                      v = new ScalarValue();
                  case OneDimensionalArray:
                      v = new Array1DValue();
                  // etc
              }
      
              v.ReadValue(variableHeader, reader);
      
              values.Add(v);
      
              variableHeader = FindNextVariable(reader);
          } 
      
          return values;
      }
      
      FindVariableType是:

      public enum VariableType {
          Scalar,
          OneDimensionalValue,
          TwoDimensionalValue,
          ThreeDimensionalValue,
          Other
      }
      
      public static VariableType FindVariableType(string header) {
          var fields = string.Split('/', header);
      
          // take the third item, parse it to determine type
      }
      

      实际实现有很多方法,但这是总体思路。

      好的,这是我的解决方案。我在代码中包含了几条注释,因此它或多或少是不言自明的

      总之,我定义了一个类(一个类用于所有变量,即使它们是多维的!),然后将所有变量存储在字典中。我认为这很简单

      要存储我的变量的类:

      public class Variable
      {
          // Properties.
          public string Database { get; set; }
          public string Name { get; set; }
          public string Type { get; set; }
          public int Dimensions { get; set; }
          public int Order { get; set; }
          public int[] Size { get; set; }
          public double[] Value { get; set; }
      
          // Default constructor.
          public Variable()
          {
          }
      
          // Constructor.
          public Y_Variable(string db, string nam, string typ, int dim, int ord, 
              int[] siz, double[] val)
          {
              this.Database = db;
              this.Name = nam;
              this.Type = typ;
              this.Dimensions = dim;
              this.Order = ord;
              this.Size = siz;
              this.Value = val;
          }
      }
      
      读取文件并在字典中存储变量的代码:

      public class Y_File2Dictionary
          {
              public static Dictionary<string, Y_Variable> File2Dictionary(string fileName)
              {
                  // Define delimiters and block comments.
                  char[] delimiterChars = { ' ', '\t', '\n', '\r' };
                  var blockComments = @"/\*(.*?)\*/";
      
                  // Read the file, remove comments, and store in array with no spaces.
                  string[] arrayAllVars = Regex
                      .Replace(File.ReadAllText(fileName), blockComments, "",
                          RegexOptions.Singleline)
                      .Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries);
      
                  // Initialize dictionary.
                  Dictionary<string, Y_Variable> dictAllVars = new 
                      Dictionary<string, Y_Variable>();
      
                  // Loop to read variables and store them in dictionary.
                  int i = 0;
                  while (i < arrayAllVars.Length)
                  {
                      // Read only variables.
                      if (!char.Equals(arrayAllVars[i][0], '/'))
                      {
                          i++;
                          continue;
                      }
      
                      // Read variable name and separate into array
                      // e.g. /YD/YDC/DCSTEC => {"", YD, YDC, DCSTEC}.
                      string[] arrayVarName = Regex.Split(arrayAllVars[i++], "/");
      
                      // Identify variable.
                      string varDb = arrayVarName[2];
                      string varName = arrayVarName[3];
                      string varTyp = (varName[0] == 'D') ? "double" : "integer";
                      int varDim = ((int)Char.GetNumericValue(varName[1]) > 0) ?
                          ((int)Char.GetNumericValue(varName[1])) : 0;
      
                      // Initiallization of variables to store order and size.
                      int varOrder = 0;
                      int[] varSize = new int[3] { 1, 1, 1 };
      
                      // Update order and size, depending on the number of dimensions.
                      switch (varDim)
                      {
                          case 1:
                              varOrder = 1;
                              Int32.TryParse(arrayAllVars[i++], out varSize[0]);
                              varSize[1] = 1;
                              varSize[2] = 1;
                              break;
                          case 2:
                              Int32.TryParse(arrayAllVars[i++], out varOrder);
                              Int32.TryParse(arrayAllVars[i++], out varSize[0]);
                              Int32.TryParse(arrayAllVars[i++], out varSize[1]);
                              varSize[2] = 1;
                              break;
                          case 3:
                              Int32.TryParse(arrayAllVars[i++], out varOrder);
                              Int32.TryParse(arrayAllVars[i++], out varSize[0]);
                              Int32.TryParse(arrayAllVars[i++], out varSize[1]);
                              Int32.TryParse(arrayAllVars[i++], out varSize[2]);
                              break;
                          default:
                              varOrder = 0;
                              varSize[0] = 1;
                              varSize[1] = 1;
                              varSize[2] = 1;
                              break;
                      }
      
                      // Determine total size of variable, get values as strings.
                      var varTotalSize = varSize[0] * varSize[1] * varSize[2];
                      string[] varValStr = new string[varTotalSize];
                      Array.Copy(arrayAllVars, i, varValStr, 0, varTotalSize);
      
                      // Convert values from string to double.
                      double[] varValDbl = new double[varTotalSize];
                      varValDbl = Array.ConvertAll(varValStr, Double.Parse);
      
                      // Add variable to dictionary.
                      if (dictAllVars.ContainsKey(varDb + "_" + varName))
                          dictAllVars.Remove(varDb + "_" + varName);
                      dictAllVars.Add(varDb + "_" + varName, new Y_Variable(varDb, varName,
                          varTyp, varDim, varOrder, varSize, varValDbl));
      
                      i += varTotalSize;
                  }
                  return dictAllVars;
              }
          }
      
      public class Y\u File2Dictionary
      {
      公共静态字典File2Dictionary(字符串文件名)
      {
      //定义分隔符和块注释。
      char[]delimiterChars={'','\t','\n','\r'};
      var blockComments=@“/\*(.*?\*/”;
      //读取文件,删除注释,并存储在数组中,不留空格。
      字符串[]arrayAllVars=Regex
      .Replace(File.ReadAllText(文件名),blockComments,“,
      RegexOptions.Singleline)
      .Split(delimiterChars、StringSplitOptions.RemoveEmptyEntries);
      //初始化字典。
      Dictionary dictAllVars=新
      字典();
      //循环读取变量并将其存储在字典中。
      int i=0;
      而(i{”,YD,YDC,DCSTEC}。
      字符串[]arrayVarName=Regex.Split(arrayAllVars[i++],“/”;
      //识别变量。
      字符串varDb=arrayVarName[2];
      字符串varName=arrayVarName[3];
      字符串varTyp=(varName[0]='D')?“double”:“integer”;
      int varDim=((int)Char.GetNumericValue(varNa)
      
      public enum VariableType {
          Scalar,
          OneDimensionalValue,
          TwoDimensionalValue,
          ThreeDimensionalValue,
          Other
      }
      
      public static VariableType FindVariableType(string header) {
          var fields = string.Split('/', header);
      
          // take the third item, parse it to determine type
      }
      
      public class Variable
      {
          // Properties.
          public string Database { get; set; }
          public string Name { get; set; }
          public string Type { get; set; }
          public int Dimensions { get; set; }
          public int Order { get; set; }
          public int[] Size { get; set; }
          public double[] Value { get; set; }
      
          // Default constructor.
          public Variable()
          {
          }
      
          // Constructor.
          public Y_Variable(string db, string nam, string typ, int dim, int ord, 
              int[] siz, double[] val)
          {
              this.Database = db;
              this.Name = nam;
              this.Type = typ;
              this.Dimensions = dim;
              this.Order = ord;
              this.Size = siz;
              this.Value = val;
          }
      }
      
      public class Y_File2Dictionary
          {
              public static Dictionary<string, Y_Variable> File2Dictionary(string fileName)
              {
                  // Define delimiters and block comments.
                  char[] delimiterChars = { ' ', '\t', '\n', '\r' };
                  var blockComments = @"/\*(.*?)\*/";
      
                  // Read the file, remove comments, and store in array with no spaces.
                  string[] arrayAllVars = Regex
                      .Replace(File.ReadAllText(fileName), blockComments, "",
                          RegexOptions.Singleline)
                      .Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries);
      
                  // Initialize dictionary.
                  Dictionary<string, Y_Variable> dictAllVars = new 
                      Dictionary<string, Y_Variable>();
      
                  // Loop to read variables and store them in dictionary.
                  int i = 0;
                  while (i < arrayAllVars.Length)
                  {
                      // Read only variables.
                      if (!char.Equals(arrayAllVars[i][0], '/'))
                      {
                          i++;
                          continue;
                      }
      
                      // Read variable name and separate into array
                      // e.g. /YD/YDC/DCSTEC => {"", YD, YDC, DCSTEC}.
                      string[] arrayVarName = Regex.Split(arrayAllVars[i++], "/");
      
                      // Identify variable.
                      string varDb = arrayVarName[2];
                      string varName = arrayVarName[3];
                      string varTyp = (varName[0] == 'D') ? "double" : "integer";
                      int varDim = ((int)Char.GetNumericValue(varName[1]) > 0) ?
                          ((int)Char.GetNumericValue(varName[1])) : 0;
      
                      // Initiallization of variables to store order and size.
                      int varOrder = 0;
                      int[] varSize = new int[3] { 1, 1, 1 };
      
                      // Update order and size, depending on the number of dimensions.
                      switch (varDim)
                      {
                          case 1:
                              varOrder = 1;
                              Int32.TryParse(arrayAllVars[i++], out varSize[0]);
                              varSize[1] = 1;
                              varSize[2] = 1;
                              break;
                          case 2:
                              Int32.TryParse(arrayAllVars[i++], out varOrder);
                              Int32.TryParse(arrayAllVars[i++], out varSize[0]);
                              Int32.TryParse(arrayAllVars[i++], out varSize[1]);
                              varSize[2] = 1;
                              break;
                          case 3:
                              Int32.TryParse(arrayAllVars[i++], out varOrder);
                              Int32.TryParse(arrayAllVars[i++], out varSize[0]);
                              Int32.TryParse(arrayAllVars[i++], out varSize[1]);
                              Int32.TryParse(arrayAllVars[i++], out varSize[2]);
                              break;
                          default:
                              varOrder = 0;
                              varSize[0] = 1;
                              varSize[1] = 1;
                              varSize[2] = 1;
                              break;
                      }
      
                      // Determine total size of variable, get values as strings.
                      var varTotalSize = varSize[0] * varSize[1] * varSize[2];
                      string[] varValStr = new string[varTotalSize];
                      Array.Copy(arrayAllVars, i, varValStr, 0, varTotalSize);
      
                      // Convert values from string to double.
                      double[] varValDbl = new double[varTotalSize];
                      varValDbl = Array.ConvertAll(varValStr, Double.Parse);
      
                      // Add variable to dictionary.
                      if (dictAllVars.ContainsKey(varDb + "_" + varName))
                          dictAllVars.Remove(varDb + "_" + varName);
                      dictAllVars.Add(varDb + "_" + varName, new Y_Variable(varDb, varName,
                          varTyp, varDim, varOrder, varSize, varValDbl));
      
                      i += varTotalSize;
                  }
                  return dictAllVars;
              }
          }