Заменить пробел подчеркиванием - PullRequest
7 голосов
/ 10 марта 2011

Я пытаюсь написать что-то, что заменит все пробелы в строке подчеркиванием.

То, что у меня есть.

string space2underscore(string text)
{
    for(int i = 0; i < text.length(); i++)
    {
        if(text[i] == ' ')
            text[i] = '_';
    }
    return text;
}

По большей части это будет работать, если бы я делал что-то вроде.

string word = "hello stackoverflow";
word = space2underscore(word);
cout << word;

Это вывело бы "hello_stackoverflow", что как раз то, что я хочу.

Однако, если бы я сделал что-то вроде

string word;
cin >> word;
word = space2underscore(word);
cout << word;

Я бы просто получил первое слово, "привет".

Кто-нибудь знает решение для этого?

Ответы [ 5 ]

16 голосов
/ 10 марта 2011

У вас исправлена ​​проблема getline, но я просто хотел сказать, что Стандартная библиотека содержит много полезных функций. Вместо свернутого вручную цикла вы можете сделать:

std::string space2underscore(std::string text)
{
    std::replace(text.begin(), text.end(), ' ', '_');
    return text;
}

Это работает, это быстро, и это на самом деле выражает то, что вы делаете.

14 голосов
/ 10 марта 2011

Проблема в том, что cin >> word будет читать только в первом слове.Если вы хотите работать с одним целым одновременно, вы должны использовать std::getline.

Например:

std::string s;
std::getline(std::cin, s);
s = space2underscore(s);
std::cout << s << std::endl;

Также вы можете захотетьпроверьте, что вы действительно смогли прочитать строку.Вы можете сделать это следующим образом:

std::string s;
if(std::getline(std::cin, s)) {
    s = space2underscore(s);
    std::cout << s << std::endl;
}

Наконец, как примечание, вы, вероятно, могли бы написать свою функцию более понятным способом.Лично я написал бы это так:

std::string space2underscore(std::string text) {
    for(std::string::iterator it = text.begin(); it != text.end(); ++it) {
        if(*it == ' ') {
            *it = '_';
        }
    }
    return text;
}

Или для бонусных баллов используйте std::transform!

РЕДАКТИРОВАТЬ: Если это произойдетчтобы быть достаточно удачливым, чтобы иметь возможность использовать функции c ++ 0x (и я знаю, что это здорово, если), вы можете использовать лямбда-выражения и std::transform, что приводит к некоторому очень простому коду:

std::string s = "hello stackoverflow";
std::transform(s.begin(), s.end(), s.begin(), [](char ch) {
    return ch == ' ' ? '_' : ch;
});
std::cout << s << std::endl;
5 голосов
/ 10 марта 2011

Проблема в том, что вы понимаете std::cin из библиотеки iostream: использование оператора >> в потоке с std::string в качестве аргумента правой стороны занимает только одно слово за раз ( используя пробел для разделения).

Вместо этого вам нужно использовать std::getline(), чтобы получить вашу строку.

1 голос
/ 06 мая 2017

Для современного подхода C ++ 1x у вас есть опция std :: regex_replace .

#include <regex>
#include <string>
#include <cstdlib>
#include <iostream>

using std::cout;
using std::endl;
using std::regex;
using std::string;
using std::regex_replace;

int main( const int, const char** )
{
   const auto target = regex{ " " };
   const auto replacement = string{ "_" };
   const auto value = string{ "hello stackoverflow" };

   cout << regex_replace( value, target, replacement ) << endl;

   return EXIT_SUCCESS;
}

Плюсы : меньше кода.

Минусы : Регулярные выражения могут скрывать намерения.

0 голосов
/ 10 марта 2011

Заменить

cin >> word;

С

getline(cin, word);
...