Цикл бросил без причины - PullRequest
       11

Цикл бросил без причины

1 голос
/ 29 августа 2011

У меня вопрос по поводу C ++.Это моя текущая функция:

string clarifyWord(string str) {
    //Remove all spaces before string
    unsigned long i = 0;
    int currentASCII = 0;

    while (i < str.length()) {
        currentASCII = int(str[i]);
        if (currentASCII == 32) {
            str.erase(i);
            i++;
            continue;
        } else {
            break;
        }
    }

    //Remove all spaces after string
    i = str.length();
    while (i > -1) {
        currentASCII = int(str[i]);
        if (currentASCII == 32) {
            str.erase(i);
            i--;
            continue;
        } else {
            break;
        }
    }
    return str;
}

Просто чтобы разобраться с основными и очевидными вещами, у меня есть #include <string> и using namespace std;, поэтому у меня есть доступ к строковым функциям.

Дело в том, что цикл завершается, а иногда пропускает второй цикл.Я передаю в str значение " Cheese ", и оно должно удалить все пробелы перед строкой и после строки.

В основной функции я также назначаю переменную clarifyWord(str), гдеstr выше.Кажется, это не распечатывается с использованием cout << str;.

Есть ли что-то, чего мне не хватает при печати строк или зацикливании строк?Также код ASCII 32 равен Space.

Ответы [ 5 ]

2 голосов
/ 29 августа 2011

Хорошо, поэтому вызываемая функция стирания выглядит следующим образом:

string& erase ( size_t pos = 0, size_t n = npos );

Параметр n - это количество элементов, которые нужно удалить.Npos означает, что нужно удалить все до конца строки, поэтому установите второй параметр равным 1.

str.erase(i,1)

[EDIT]

Вы можете изменить первый цикл так:

while (str.length() > 0 && str[0] == ' ')
{
   str.erase(0,1);
}

и второй цикл к этому:

while (str.length() > 0 && str[str.length() - 1] == ' ')
{
   str.erase(str.length() - 1, 1);
}
1 голос
/ 29 августа 2011

Вы используете erase (изменяющий строку), пока вы в цикле проверяете его размер. Это опасный способ обработки строки. Когда вы возвращаете новую строку, я бы порекомендовал вам сначала найти первое вхождение в строке непробельного символа, а затем последнее, а затем вернуть подстроку. Что-то вроде (не проверено):

size_t init = str.find_first_not_of(' ');
if (init == std::string::npos)
    return "";
size_t fini = std.find_last_not_of(' ');
return str.substr(init, fini - init + 1);

Понимаете, без петель, стираний и т. Д.

1 голос
/ 29 августа 2011

Во втором цикле вы не можете инициализировать i в str.length ().

str [str.length ()] будет после конца вашей строки и вряд ли будет пробелом (таким образом, вызывая разрыв второго цикла).

0 голосов
/ 29 августа 2011

Вы используете стирание неправильно.Он будет удален из pos в npos.
т.е. string & erase (size_t pos = 0, size_t n = npos);

См .: http://www.cplusplus.com/reference/string/string/erase/

Лучший способ сделать этоэто отметить положение первого не пробела и где пробелы находятся в конце строки.Затем дважды воспользуйтесь substr или erase.

Вам также не нужно заниматься этим:

 currentASCII = int(str[i]);
       if (currentASCII == 32) {

Вместо этого сделайте следующее:

if (str[i] == ' ') {

С чем, я думаю, вы согласитесь, намного легче читать.

Итак, вы можете немного сократить его с помощью чего-то вроде: (не проверено, но не должно быть далеко)

string clarifyWord(string str) {
  int start = 0, end = str.length();
  while (str[start++] == ' ');
  while (str[end--] == ' ');
  return str.substr(start, end);
}
0 голосов
/ 29 августа 2011

без знака долго я ... while (i > -1) Ну, это не правильно, не так ли?Как вы ожидаете, что это сработает?Компилятор фактически преобразует оба операнда в один и тот же тип: while (i > static_cast<unsigned long>(-1)).И это просто еще один способ написать ULONG-MAX, то есть while (i > ULONG_MAX).Другими словами, while(false).

...