Pergunta

Houve um comentário passando em um livro meu sobre pessoas introduzir vírgulas em números inteiros e bagunçar o seu programa, mas não deu mais detalhes. Isso me fez pensar, então eu tentei escrever um pouco algoritmo para tomar uma std :: string e remover todos os caracteres não-inteiros. Este código compila mas ignora mais saída. Por que não é qualquer coisa que está sendo atribuído a NewString? Faz se (isdigit (fstring [i])) avaliar a verdade do endereço ele está apontando para segurar um dígito?

//little algorithm to take the non-integers out of a string
//no idea on efficiency

#include <iostream>
#include <string>

int main()
{
    std::cout << "Enter a number with non-integer characters: ";

    std::string fstring; 
    getline(std::cin, fstring);

    std::string newstring;

    int i = 0, x = 0;

    while (i != fstring.length())
    {
        if (isdigit(fstring[i]))
        {
            newstring[x] = fstring[i];
            i++;
            x++;
        }
        else
        {
           i++;
        }
    }

    std::cout << std::endl;
    std::cout << newstring;
    system("PAUSE");
}

questão secundária, que talvez pertence em outros lugares: como você converter uma string para um int (ou um número de ponto flutuante)

Foi útil?

Solução

newString é de comprimento 0, de modo NewString [x] em que x = 0 é realmente ilegal. Você deve anexar a string usando: newstring.append (1, fstring [i])

Para a questão secundária, olhar para atoi (), atof (), strtol (0, strtof () funções.

Outras dicas

Cordas são como matrizes, mas o construtor padrão para uma string cria uma cadeia vazia. Por que deveria alocar mais memória do que ele precisa? Mesmo se isso acontecer, não há nenhuma dizendo o quanto, ou se ele vai ser grande o suficiente para uma cópia filtrada da fstring. Estou impressionado que não falha.

Uma modificação simples seria mudar:

std::string newstring;

para:

 std::string newstring(fstring.length(), '\0')

E após o add loop:

 newstring.resize(x);

Isto irá assegurar que newstring terá pelo menos o suficiente quarto (provavelmente mais) durante a filtração e serão aparadas para baixo para o tamanho apropriado quando você está filtragem acabado. Você pode também estar interessado na função std::remove_copy_if em <algorithm>.

por exemplo.

struct isnotdigit { bool operator()(char c) { return !isdigit(c); } };

std::string newstring(fstring.length(), '\0');
std::string::iterator i = std::remove_copy_if(fstring.begin(), 
  fstring.end(), newstring.begin(), isnotdigit());
newstring.erase(i, newstring.end());

Como para converter uma string para um inteiro / float, além de atoi, strtol, atof, strtof, etc. funções já mencionado você também pode fazer uso da biblioteca iostream:

 #include <sstream>
 std::string integer("23");
 std::istringstream iss(integer);
 int result;
 iss >> result;

 std::string floatingpoint("3.14");
 std::istringstream iss2(floatingpoint);
 double result2;
 iss2 >> result2;

Além disso, se você estiver familiarizado com a família printf de funções que você pode estar interessado em scanf, sscanf

 const char *s = "23";
 int result;
 sscanf(s, "%d", &result);

Expansão da resposta do Shing Yip:

Para remover os não-dígitos:

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

using namespace std;

int main() {
    string fstring;
    getline(cin, fstring);
    fstring.erase(
        remove_if(fstring.begin(), fstring.end(),
            not1(ptr_fun(static_cast<int(*)(int)>(isdigit)))
        ),
        fstring.end()
    );

    cout << fstring << "\n";
}

Eu não sei por que isso static_cast é necessário, no entanto. Eu acho que algo de ambíguo sobre isdigit sem ele. [Edit: Se você não fizer "usando namespace std", então você não precisa dele, por isso é minha culpa por ser preguiçoso escrever código exemplo.]

discutível É se este é mais simples do que rolando seu próprio loop:

#include <iostream>
#include <string>

using namespace std;

int main() {
    string fstring, ins;
    getline(cin, ins);
    for (string::iterator it = ins.begin(); it != ins.end(); ++it) {
        if (isdigit(*it)) fstring.push_back(*it);
    }
    cout << fstring << "\n";
}

E C ++ 0x terá copy_if, que foi deixado de fora, basicamente, por acidente, e é trivial para implementar:

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

int main() {
    std::string fstring, ins;
    std::getline(std::cin, ins);
    std::copy_if(ins.begin(), ins.end(), 
        std::back_inserter(fstring), isdigit);
    std::cout << fstring << "\n";
}

Para converter para int (ou float):

int i = boost::lexical_cast<int>(fstring);

Ou se você não tem impulso:

#include <sstream>

int i = 0;
std::stringstream(fstring) >> i;

Note que você tem que inicializar i, caso contrário não será definido se fstring está vazio.

Para remover dígitos:

fstring.erase(
      std::remove_if(fstring.begin(), fstring.end(), &isdigit), 
      fstring.end());

Para converter string para int / float /...:

int n1 = boost::lexical_cast<int>("123");
float n2 = boost::lexical_cast<float>("123.456");
  • string de número de ponto flutuante:

Você precisa #include <cstdlib>

float strtof(const char *nptr, char **endptr);

Por exemplo:

 float f = strtof("3.4",NULL);
  • string para inteiro

Você precisa #include <cstdlib>

int atoi(const char *numPtr);

Observe que estes são C -. Funções, e não C ++, então você precisa usar o método c_str () em std :: string para obter o C-string

const char* c_str ( ) const;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top