2012-05-28 2 views
3

Я пытаюсь удалить все знаки пунктуации из std :: string в C++. Мой текущий код:Как прервать std :: string в C++?

string str_in; 
string::size_type i, j; 

cout << "please input string with punctuation character..." << endl; 
cin >> str_in; 

for (i = 0, j = 0; i != str_in.size(); ++i) 
    if (!ispunct(str_in[i])) 
     str_in[j++] = str_in[i]; 

str_in[j] = '\0'; 

cout << str_in << endl; 

str_in[j] = '\0'; не так ли?

+0

Я согласен, что 'str_in [у] =«\ 0'' неверно, так как это не является подходящим способом завершите строку 'std :: string'. В чем вопрос? – jamesdlin

+0

Как прервать std :: string в C++ – iverson

+0

Было бы полезно, если бы вы перефразировали вопрос. В отличие от строк стиля C, 'std :: string' не определены для использования терминатора. Я думаю, вы пытаетесь удалить все знаки препинания из 'std :: string', поэтому' 'foo.bar + baz' 'становится' "foobarbaz" '. Если это так, это не имеет никакого отношения к прекращению. –

ответ

4

Если вы хотите обрезать str_in с помощью первых j символов, вы можете сказать str_in.resize(j).

Если вы хотите использовать стандартную библиотеку можно применить erase-remove идиомы, как это:

#include <algorithm> 
#include <iostream> 
#include <string> 

int main() 
{ 
    std::string str_in; 
    std::getline(std::cin, str_in); 

    // Here is where the magic happens... 
    str_in.erase(std::remove_if(str_in.begin(), str_in.end(), ::ispunct), str_in.end()); 

    std::cout << str_in << '\n'; 

    return 0; 
} 
+0

Идиома erase/remove_if - это, конечно, единственный разумный способ решения этой проблемы на C++. Но передача ':: ispunct', поскольку предикат приводит к неопределенному поведению, поскольку вы не можете безопасно называть' :: ispunct' символом 'char'. (Вход в ':: ispunct' должен находиться в диапазоне' [0, UCHAR_MAX] 'или' EOF'.) –

0

Я думаю, что str_in[j] = '\0' неверно, когда строка не имеет никаких знаков препинания.

+0

В любом случае это не является подходящим способом для завершения 'std :: string'. Например, 'str_in.size()' возвращает неверное значение. – jamesdlin

+0

Этот метод полезен в C, но он не работает на C++! – iverson

+0

@jamesdlin о, да. Это std :: string, а не char []. Я забыл об этом. – RolandXu

0

Вместо изменения ту же строку, создать новую строку (например, str_out) и добавить к этому:

str_out += str_in[i]; 
+0

Я знаю этот метод, я просто хочу использовать ** ту же строку ** для достижения этой функции. – iverson

+0

@iverson Затем либо скопируйте в 'str_in', когда закончите, либо используйте [' substr'] (http://en.cppreference.com/w/cpp/string/basic_string/substr): 'str_in = str_in.substr (0 , j); ' –

+2

Или просто скажите' str_in.resize (j) ' – Blastfurnace

1

++ строка типа C не реализован, чтобы быть нулем (хотя и c_str() вызов будет дать вам нулевую строку завершающуюся)

Так что да, str_in[j] = '\0' неправильно, по крайней мере по двум причинам:.

  1. str_in.length() не будет отображать размер строки, которую вы ожидаете, с удалением пунктуации.
  2. Нулевая charatcter является дополнительным чартерный, который будет отправлен в любой выходной поток,
    , такие как cout << str_in;

Используя std::string класс, который вы, вероятно, не oveeride тот же буфер, но, вероятно, использовать str_out буфер вместо которой будет иметь нужную длину после того, как вы скопируете все нужные (т. е. исключая символ пунктуации), ИЛИ вы должны вместо этого отрегулировать длину str_in вместо добавления нулевого значения. Аргентина, Аргентина:

Смежные вопросы