Не удалось использовать SUBSTRING в TryParse - PullRequest
0 голосов
/ 19 апреля 2011

Я обнаружил ошибку в своем коде, когда подстрока не работает, она говорит: "startIndex не может быть больше, чем длина строки"

 static int MyIntegerParse(string possibleInt)
    {
        int i;
        return int.TryParse(possibleInt.Substring(2), out i) ? i : 0;        
    }

Я использовал процедуру здесь:

var parsed = File.ReadLines(filename)
            .Select(line => line.Split(' ')     
                .Select(MyIntegerParse)
                .ToArray())
            .ToArray();

Но я не понимаю, почему это ошибка, потому что я уже использовал подстроку раньше, и она работает, могу ли я попросить помощи здесь? Thnaks.

образец строки:

10192 20351 30473 40499 50449 60234 
10192 20207 30206 40203 50205 60226 
10192 20252 30312 40376 50334 60252

Ответы [ 5 ]

1 голос
/ 19 апреля 2011

Substring завершится ошибкой, если possibleInt содержит менее двух символов, поэтому вы должны добавить этот тест в свой код.Я подозреваю, что ваш Split вызов производит пустую строку при некоторых обстоятельствах.Эта пустая строка передается в ваш анализатор int, который затем завершается ошибкой при вызове Substring.Таким образом, вы, вероятно, должны сделать две вещи:

  • Избавиться от пустых строк в разбиении
  • Обрабатывать короткие или пустые строки преднамеренно в коде синтаксического анализа

Избавиться от пустых строк довольно просто:

var parsed = File.ReadLines(filename)
            .Select(line => line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(MyIntegerParse)
                .ToArray())
            .ToArray();

Добавление преднамеренной обработки пустых строк можно сделать так:

static int MyIntegerParse(string possibleInt)
{
    if (string.IsNullOrEmpty(possibleInt) || possibleInt.Length < 2)
    { 
        return 0;
    }

    int i;
    return int.TryParse(possibleInt.Substring(2), out i) ? i : 0;        
}

... или если вы являетесь поклонникомкомпактные и трудно читаемые конструкции:

static int MyIntegerParse(string possibleInt)
{
    int i;
    return (!string.IsNullOrEmpty(possibleInt) 
        && possibleInt.Length >= 2
        && int.TryParse(possibleInt.Substring(2), out i)) ? i : 0;        
}

Нет, я решил вернуть 0, когда получаю слишком короткие строки.В вашем случае может иметь смысл вернуть какое-то другое значение, сгенерировать исключение или использовать оператор Debug.Assert.

0 голосов
/ 19 апреля 2011

Вы получаете это исключение, потому что вы пытаетесь получить подстроку строки, начиная с индекса, который больше длины строки.

someString.Substring(x) даст вам подстроку someString начиная с позиции x в строке, и она начинается с нуля.Вы получаете это исключение, потому что в этом случае 2 находится за пределами диапазона определенной длины строки.

Придерживайтесь try-catch вокруг него или точки останова, и вы увидите строку, вызывающую это исключение, длиныменее 3.

0 голосов
/ 19 апреля 2011

Строка, которую вы пытаетесь проанализировать, не такая длинная. Из спецификации C # на Подстрока :

The zero-based starting character position of a substring in this instance. 

В строке, которую вы передаете, содержится 0 или 1 символ. Вы должны изменить свой код, чтобы справиться с такой ситуацией.

РЕДАКТИРОВАТЬ: Кроме того, вы должны удалить пустые элементы из вашего файла, используя перегрузку split:

.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntires)
0 голосов
/ 19 апреля 2011

Добавьте это перед вашим оператором возврата и посмотрите, поможет ли это вам выяснить, что происходит:

Debug.Assert(!string.IsNullOrEmpty(possibleInt) && possibleInt.Length > 2);

При работе в режиме отладки это вызовет исключение, если два вышеупомянутых случая не будут выполнены.

Вы также можете использовать Кодовый контракт , например:

Contract.Assert(!string.IsNullOrEmpty(possibleInt) && possibleInt.Length > 2);
0 голосов
/ 19 апреля 2011

Строка possibleInt должна содержать не менее двух символов. Если это не так, вы увидите ошибку, которую вы описали.

...