2012-10-18 23 views
7

Znalazłem ten kod online jako szablon do wykonywania łańcucha znaków w float/int/double conversion. To tylko tutaj, więc mam coś do odniesienia dla pytania ...String to float using stringstream

Chcę, aby użytkownik wprowadził liczbę jako ciąg znaków, przekonwertował ją na wartość zmiennoprzecinkową, przetestował pod kątem powodzenia i porzucił, jeśli wpis był " Q 'lub wydrukuj "Niepoprawne dane wejściowe", jeśli nie jest to znak "Q'uit" i wróć, aby uzyskać więcej danych wejściowych.

Jaka jest składnia testu niepowodzenia konwersji? Czy byłby to ss.fail()?

// using stringstream constructors. 
#include <iostream> 
#include <sstream> 
using namespace std; 

int main() { 

    int val; 
    stringstream ss (stringstream::in | stringstream::out); 

    ss << "120 42 377 6 5 2000"; 

    /* Would I insert an 

    if(ss.fail()) 
     { 
     // Deal with conversion error } 
     } 

    in here?! */ 


    for (int n=0; n<6; n++) 
    { 
    ss >> val; 
    cout << val*2 << endl; 
    } 

    return 0; 
} 
+0

co składnia błąd otrzymujesz? –

Odpowiedz

9

Twój kod nie jest zbyt pomocny. Ale jeśli rozumiem, że masz rację, zrób to tak, jak to, że nie ma potrzeby używania polecenia "nie powiodło się".

2

Faktycznie, najprostszy sposób na konwersję ciąg do pływaka jest prawdopodobnie boost::lexical_cast

#include <string> 
#include <boost/lexical_cast.hpp> 

int main() { 
    std::string const s = "120.34"; 

    try { 
     float f = boost::lexical_cast<float>(s); 
    } catch(boost::bad_lexical_cast const&) { 
     // deal with error 
    } 
} 

Oczywiście w większości przypadków po prostu nie połowu wyjątek od razu i niech to bańka górę łańcucha połączenia, więc koszt jest znacznie zredukowany.

0

Niektóre żądanych przez pierwotnego pytania cechy to:

  1. Wyjście dwa razy wartość wejścia unosi
  2. raport nieprawidłowych wejścia
  3. nadal szuka pływaków nawet po napotkaniu nieprawidłowymi Wejścia
  4. zatrzymaj się po wyświetleniu znaku "Q"

Myślę, że następujący kod spełnia abo ve prośba:

// g++ -Wall -Wextra -Werror -static -std=c++11 -o foo foo.cc 

#include <iostream> 
#include <sstream> 

void run_some_input(void) 
{ 
    std::string  tmp_s; 

    int not_done = 1; 

    while(not_done && getline(std::cin, tmp_s)) 
    { 
     std::stringstream ss; 

     ss << tmp_s; 

     while(! ss.eof()) 
     { 
      float tmp_f; 
      if (ss >> tmp_f) 
      { 
       std::cout << "Twice the number you entered: " 
          << 2.0f * tmp_f << "\n"; 
      } 
      else 
      { 
       ss.clear(); 
       std::string tmp_s; 
       if(ss >> tmp_s) 
       { 
        if(! tmp_s.compare("Q")) 
        { 
         not_done = 0; 
         break; 
        } 
        std::cout << "Invalid input (" << tmp_s << ")\n"; 
       } 
      } 
     } 
    } 
} 

int main(int argc __attribute__ ((__unused__)), char **argv __attribute__ ((__unused__))) 
{ 
    run_some_input(); 
} 

Oto sesja próbki:

$ ./foo 
1 
Twice the number you entered: 2 
3 4 
Twice the number you entered: 6 
Twice the number you entered: 8 
5 bad dog Quit 6 8 Q mad dog 
Twice the number you entered: 10 
Invalid input (bad) 
Invalid input (dog) 
Invalid input (Quit) 
Twice the number you entered: 12 
Twice the number you entered: 16