【问题标题】:how to fix error with Substring and IndexOf c#如何修复 Substring 和 IndexOf c# 的错误
【发布时间】:2015-07-03 00:42:31
【问题描述】:

我不知道如何修复这个运行时错误:

http://postimg.org/image/hh9vl7hi9/

roomsInfo 的值为:“@114|mag|nir|1||dan|nir|1||\0” 当值为:“dan|nir|1||\0”时它会崩溃 (第二次)当我尝试这样做时:

roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|') + 1, roomsInfo.IndexOf('\0'));

这是完整的代码:

    String roomsInfo = Program.sendToServ("@10||");
        String[] room_name = new String[100];
        String[] admin_name = new String[100];
        String[] number_of_people = new String[100];
        int check = 0, count = 0;
        if(roomsInfo.IndexOf('\0') > 5)
        {
            roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|')+1, roomsInfo.IndexOf('\0'));
            while (roomsInfo[roomsInfo.IndexOf('|') + 2] != '\0' && roomsInfo[roomsInfo.IndexOf('|') + 1] != '\0') // @114|roomName1|RoomAdmin1|count1||roomName2|RoomAdmin2|count2||
            {
                if (check == 0)
                {
                    room_name[count] = roomsInfo.Substring(0, roomsInfo.IndexOf('|'));
                    check = 1;
                    roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|') + 1, roomsInfo.IndexOf('\0'));
                }
                if (check == 1)
                {
                    admin_name[count] = roomsInfo.Substring(0, roomsInfo.IndexOf('|'));
                    check = 2;
                    roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|') + 1, roomsInfo.IndexOf('\0'));
                }
                if (check == 2)
                {
                    number_of_people[count] = roomsInfo.Substring(0, roomsInfo.IndexOf('|'));
                    check = 0;
                    count++;
                    roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|') + 2, roomsInfo.IndexOf('\0'));
                }

            }
        }

谢谢! 尼尔

【问题讨论】:

  • 您应该考虑以roomsInfo.Split('|') 而不是roomsInfo.IndexOf('|') 开头,它将将该字符串的每个部分放入一个数组中,这样您应该更容易使用。

标签: c# string substring indexof


【解决方案1】:

为了正确地进行子串,您必须获取子串的长度,就像在数学中获取向量的长度一样。

例如,您在一条线上有两个点。比如说 5 和 13。要获得 5 和 13 之间的长度,你必须从 13 中减去 5。所以13 - 5 = 8

        int startIndex = roomsInfo.IndexOf('|') + 1;
        int endIndex = roomsInfo.IndexOf('\0');
        int length = endIndex - startIndex;

        roomsInfo = roomsInfo.Substring(startIndex, length); // Will Get nir|1||

如果您也想获取 Last char。长度必须加 1

        roomsInfo = roomsInfo.Substring(startIndex, length + 1); // Will Get nir|1||\0

根据我在您的代码中看到的内容。你的子字符串都错了。所以你必须对他们所有人都这样做。

一线解决方案

roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|') + 1, roomsInfo.IndexOf('\0') - roomsInfo.IndexOf('|') - 1);

同样,如果您也想获取最后一个字符,则必须将长度加 1。

【讨论】:

  • 你写的东西是行不通的,因为它使 /0 失望了(你写的最后一行我放在开头)
  • 如果你在长度上加一,它会占用它。但请注意 /0 是空的 char 。所以我认为你无法通过调试看到它@user3346907
【解决方案2】:

我猜这可能与 || 有关在记录(我假设这是记录分隔符吗?)和您的子字符串索引之间。

格伦所说的可以将记录拆分为字段,但是在您的情况下,您的所有记录都链接在一起并且(我假设由 || 分隔?)最后以空零终止。因此,在将记录拆分为字段之前,您首先需要将字符串拆分为一组记录。

  struct RoomInfo
  {
    public String RoomName;
    public String AdminName;
    public String WhatIsNir;
    public int NumberOfPeople;
  }

  var roomsInfo = new List<RoomInfo>();
  String allData = "@114|mag|nir|1||@115|dan|nir|1||\0".TrimEnd('\0');
  String[] delimiters = new string[] { "||" };
  String[] records = allData.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);

  foreach (var record in records)
  {
    String[] fields = record.Split('|');
    roomsInfo.Add(new RoomInfo
      {
        RoomName = fields[0],
        AdminName = fields[1],
        WhatIsNir = fields[2],
        NumberOfPeople = int.Parse(fields[3])
      });
  }

另一个问题可能是您的数据和字段不匹配。 IE。您的三个字段在以下字符串中在哪里重复? “@114|mag|nir|1||dan|nir|1||\0”。我在该字符串中看到了四个字段,因此我在上面的示例中添加了一个(房间名称)。

当然,使用此解决方案意味着对您的数据格式有承诺。如果这是您可以更改的内容(即不是由第 3 方确定的),那么我会将其更改为更标准的内容。即使是基本形式的 CSV 也会类似,但可能会更好。

【讨论】:

    【解决方案3】:

    您的实现非常复杂。几行代码就可以搞定,更容易维护:

        string roomsInfo = Program.sendToServ("@10||");
        var room_name = new List<string>();
        var admin_name = new List<string>();
        var number_of_people = new List<string>();
    
        if(roomsInfo.IndexOf('\0') > 5)
        {
            roomsInfo = roomsInfo.Substring(roomsInfo.IndexOf('|')+1, roomsInfo.IndexOf('\0'));
            var records = roomsInfo.Split(new[] {"||"}, StringSplitOptions.None);
            foreach (var rec in records)
            {
                var fields = rec.Split(new [] {'|'}, StringSplitOptions.None);
                room_name.Add(fields[0]);
                admin_name.Add(fields[1]);
                number_of_people.Add(fields[2]);
            } 
        }
    

    这当然可以改进,以控制异常。

    【讨论】:

      猜你喜欢
      • 2011-08-18
      • 1970-01-01
      • 1970-01-01
      • 2013-05-21
      • 1970-01-01
      • 2021-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多