4

I have a text document which looks something like this:

user_name1 1.575
user_name2 3.636
user_name3 2.647
user_name4 5.532
user_name5 4.253

What i am trying to do is, to get these numbers from .txt file into console and save them as variables. I know how to read .txt file in console and I found some answers here how to get each line separately as strings, but i can't get these doubles. Is there some kind of function or whatsoever that goes through strings and finds numbers?

I tried with this:

1) get string of each line 2) loop through them and check ASCII code and if it is a number I saved next 3 or 4 charachters

But its not working very well. Thanks for your help in advance.

EDIT:

string line;

ifstream banka ("banka.txt");

double numbers[5];
if(banka.is_open()) {
    for(int i=0; i<5; i++) {
        getline(cin,line);
        size_t space=line.find(' ');
        string numStr=line.substr(space+1);
        double num = stod(numStr);
        numbers[i]=num;

    }
    banka.close();
}
else {
    cout<<"Unable to open file."<<endl;
}
spafrou
  • 548
  • 1
  • 6
  • 19

4 Answers4

6

Why not simply this ?

std::ifstream fin("input.txt");
std::string str;
double num;

while (fin >> str >> num)
{

    std::cout << str << " :" << num <<std::endl;
}
P0W
  • 46,614
  • 9
  • 72
  • 119
  • because it's not reliable. –  Jan 13 '14 at 19:30
  • @H2CO3 I won't argue with [these](http://stackoverflow.com/users/1870232/p0w) people, but exactly why its not reliable ? I think it is as long as they are as separated by white space – P0W Jan 13 '14 at 19:41
  • because `operator>>` is subject to `iomanip` stream manipulators and other "funny" stuff, so you can never be sure that it does what's advertised. Basically, this operator has the very same problem as `scanf()`: it tries to do two things at once (getting user input and parsing it), and - not surprisingly - it fails to do its job properly, similar to its C counterpart. –  Jan 13 '14 at 19:47
  • @H2CO3 How does `scanf()` fail to do its job? I know it isn't type-safe, but that isn't a parallel in this situation. – David G Jan 13 '14 at 20:27
  • @P0W: Aww, I haven't made the list. :) – John Dibling Jan 13 '14 at 20:39
  • @0x499602D2 It's messy, its usage is counter-intuitive and it's prone to UB (although the last assertion does not apply to `operator>>`). –  Jan 13 '14 at 20:41
1

This:

std::string ln; // line
while (std::getline(std::cin, ln)) {
    std::size_t space = ln.find(' ');
    std::string nameStr = ln.substr(0, space);
    std::string numStr = ln.substr(space + 1);
    double num = std::stod(numStr);
}
  • I'll try this one out :) – spafrou Jan 13 '14 at 19:35
  • 1
    I tried this code and used cout to check in console, but it's not working though i think i am doing something wrong. And one more thing: I always have 5 lines, so that means 5 double numbers. Can I simply use for loop instead of while and save those doubles into an array? Thank you for your help – spafrou Jan 13 '14 at 20:07
  • @spafrou It **is** working. Yes, you can use a for loop. Note: don't use the currently top rated (albeit not too good) answer, it's dangerous. –  Jan 13 '14 at 20:08
  • 1
    can you look up my edited code? It gives me an error: libc++abi.dylib: terminating with uncaught exception of type std::invalid_argument: stod: no conversion – spafrou Jan 13 '14 at 20:17
  • @spafrou then you are passing it a string that does not represent a number. since you haven't shown the format of your file, I have no idea what's going on. –  Jan 13 '14 at 20:42
  • I have a "banka.txt" file and it looks exactly like described in my question. I changed only names – spafrou Jan 13 '14 at 20:51
  • Wow i did it now. Thank you very much for your help. Marked as answered. – spafrou Jan 13 '14 at 20:57
0

If you know the line contains one space and only one space:

string dstr = line.substr(line.find(' ')+1);
double d = strtod(dstr.c_str(), NULL);
ichramm
  • 6,437
  • 19
  • 30
0

You can use std::istringstream to parse a string:

std::istringstream iss("user_name1 1.575");
std::string str;
double d;
iss >> str >> d;
derikon
  • 3
  • 2