【问题标题】:Reading an int from a file returns ASCII从文件中读取 int 会返回 ASCII
【发布时间】:2012-01-04 23:02:54
【问题描述】:

我目前正在制作游戏,但我似乎无法从文本文件中读取值。出于某种原因,当我读取该值时,它给了我该值的 ASCII 码,而不是我将其写入文件时的实际值本身。我已经尝试过所有的 ASCII 转换函数和字符串转换函数,但我似乎无法弄清楚。

我使用一个二维整数数组。我使用嵌套的 for 循环将每个元素写入文件。我查看了文件并且值是正确的,但我不明白为什么它返回 ASCII 码。这是我用来写入和读取文件的代码:

写入文件:

for (int i = 0; i < level.MaxRows(); i++)
{
    for (int j = 0; j < level.MaxCols(); j++)
    {
        fileWrite.Write(level.GetValueAtIndex(i, j) + " ");
        //Console.WriteLine(level.GetValueAtIndex(i, j));
    }

    //add new line
    fileWrite.WriteLine();
}

这是我从文件中读取值的代码:

string str = "";
int iter = 0;    //used to iterate in each column of array

for (int i = 0; i < level.MaxRows(); i++)
{
    iter = 0;
    //TODO: For some reason, the file is returning ASCII code, convert to int
    //keep reading characters until a space is reached.
    str = fileRead.ReadLine();

    //take the above string and extract the values from it.
    //Place each value in the level.
    foreach (char id in str)
    {
        if (id != ' ')
        {
            //convert id to an int
            num = (int)id;
            level.ChangeTile(i, iter, num);
            iter++;
        }
    }

这是我用来读取值的循环的最新版本。读取其他值很好;只是当我到达阵列时,事情就出错了。我想我的问题是,为什么会发生向 ASCII 的转换?如果我能弄清楚这一点,那么我也许可以解决这个问题。我正在使用 XNA 4 制作我的游戏。

【问题讨论】:

    标签: c# arrays xna ascii


    【解决方案1】:

    这是转换为 ascii 的地方:

    fileWrite.Write(level.GetValueAtIndex(i, j) + " ");
    

    + 运算符将 GetValueAtIndex 返回的整数隐式转换为字符串,因为您将其添加到字符串中(真的,您期望会发生什么?)

    此外,ReadLine 方法返回一个字符串,所以我不确定为什么您会期望一个数值神奇地返回这里。如果你想写二进制数据,请查看BinaryWriter

    【讨论】:

    • 这个答案的问题是,我有其他值要写入文件,我可以很好地读取这些值。只有数组的值会引起混淆。我知道这一切都被转换为字符串。我已经删除了串联,我遇到了同样的问题。
    • level.GetValueAtIndex(i, j) 返回什么数据类型?我假设它是一个整数。
    【解决方案2】:

    这是您将字符转换为字符代码的地方:

    num = (int)id;
    

    id 变量是 char,将其转换为 int 会得到字符代码,而不是数值。

    此外,这会转换单个字符,而不是整数。例如,如果您的文本文件中有 "12 34 56 ",它将获得 1、2、3、4、5 和 6 的代码,而不是 12、34 和 56。

    您可能希望在空格上分割行,并解析每个子字符串:

    foreach (string id in str.Split(' ')) {
      if (id.Length > 0) {
        num = Int32.Parse(id);
        level.ChangeTile(i, iter, num);
        iter++;
      }
    }
    

    【讨论】:

      【解决方案3】:

      更新:我保留了旧代码(如下),假设每一行都有一条记录,但我还添加了一种不同的方法,它应该适用于多个整数一行,用空格隔开。

      一行多条记录

      str = fileRead.ReadLine();
      
      string[] values = str.Split(new Char[] {' '});
      
      foreach (string value in values)
      {
          int testNum;
      
          if (Int32.TryParse(str, out testnum))
          {
              // again, not sure how you're using iter here
              level.ChangeTile(i, iter, num);
          }
      }
      

      每行一条记录

      str = fileRead.ReadLine();
      
      int testNum;
      
      if (Int32.TryParse(str, out testnum))
      {
          // however, I'm not sure how you're using iter here; if it's related to 
          // parsing the string, you'll probably need to do something else
          level.ChangeTile(i, iter, num);
      }
      

      请注意,如果您逐行写出每个整数(即您如何通过您在上面的代码中注明的 WriteLine 执行此操作),则上述内容应该有效。如果您切换回使用 WriteLine,这应该可以工作。

      【讨论】:

      • @King 从外观上看每一行都有多条记录。
      • @Chris Shain 同意,尽管有一次它们是逐行编写的(即注释掉的 WriteLine)。我会在我的回答中更清楚地说明这一点。
      【解决方案4】:

      你有:

      foreach (char id in str)
      {
          //convert id to an int
          num = (int)id;
      

      A char 一个 ASCII 码(或者可以被认为是这样的;从技术上讲,它是一个 unicode 代码点,但假设你正在编写 ANSI 或低值 UTF -8)。

      你想要的是:

      num = (int)(id - '0');
      

      【讨论】:

        【解决方案5】:

        这个:

        fileWrite.Write(level.GetValueAtIndex(i, j) + " ");
        

        将从level.GetValueAtIndex(i, j) 返回的int 转换为字符串。假设函数返回特定 ij 的值 5,那么您将“5”写入文件。

        当您读取它时,它被读取为一个由字符组成的字符串,当您将它简单地转换为int 时,您会得到5 的ASCII 代码。你需要的是:

        foreach (char id in str)
        {
            if (id != ' ')
            {
                //convert id to an int
                num = (int)(id - '0'); // subtract the ASCII value for 0 from your current id
                level.ChangeTile(i, iter, num);
                iter++;
            }
        }
        

        但是,这仅适用于您只有一位数整数(仅 0 - 9)的情况。这可能会更好:

        foreach (var cell in fileRead.ReadLine().Split(' '))
        {
             num = Int.Parse(cell);
             level.ChangeTile(i, iter, num);
             iter++;
        }
        

        【讨论】:

        • 这里的这段代码很有希望。我在尝试时遇到错误,但如果我能弄清楚,那么我认为它会起作用。调试显示正确的值。谢谢!
        • 感谢您的帮助!我稍微更改了代码,但您的代码让我走上了解决问题的正确轨道!
        猜你喜欢
        • 2013-05-07
        • 1970-01-01
        • 1970-01-01
        • 2012-05-09
        • 1970-01-01
        • 2020-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多