2

I am using fstream to read a notepad file containing numerical data. I am using dynamic memory allocation and the data is type float. However there is rouge data in form of characters in my file - how would I write code that searches for and ignores the characters in the file, and only reads in the numbers?

I am assuming I will need to use either ignore or peek?

fstream myfile("data1");
myfile.ignore ();


or myfile.peek ();

But am a bit unsure. Any help is appreciated!

herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
Serena
  • 21
  • 1

3 Answers3

2

If it has always this format, the words and numbers are separated by whitespace, you can simply read it one string at a time and let a std::istringstream do the parsing. When this fails, you know it is not a number

std::string word;
while (myfile >> word) {
    std::istringstream is(word);
    double d;
    if (is >> d) {
        // found a number
        std::cout << d << '\n';
    } else {
        // something's wrong
        std::cerr << word << '\n';
    }
}

Update:

Due to popular demand: a stringstream works like any other stream (std::cin, std::cout or std::fstream). The main difference is that a stringstream operates on strings. This means input comes from a string instead of a file or standard input, or output goes to a string, much like it goes to standard output or a file.

Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
  • Okay, since i am a complete novice - Any chance you can explain what the term istringstream and string does (or are they just variable types?)? Sorry am really new at this! – Serena Feb 12 '14 at 13:58
  • Well, this is what books are for ;-) Please see updated answer and [The Definitive C++ Book Guide and List](http://stackoverflow.com/q/388242/1741542), of course. – Olaf Dietsche Feb 12 '14 at 14:27
0

Parsing input is like this typically requires that you extract the tokens into a string and test the content of your string against your parsing requirements. For example, when you extract into the string, you can then run a function which inserts it into a std::stringstream, then extract into the data type you're testing against, and see if it succeeds.

Another option is to check if the string is not a certain string, and convert back to the desired data type if so:

while (f >> str)
{
    if (f != "badInput")
    {
        // convert to double and add to array 
    }
}

Fortunately you can use the Boost.Regex facilities to avoid having to do most of the work yourself. Here's an example similar to yours:

#include <boost/regex.hpp>

int main()
{
    std::fstream f("test.txt");
    std::string token;

    boost::regex floatingPoint("((\\+|-)?[0-9]+)?(\\.)?([0-9]+)");

    while (f >> token)
    {
        if (boost::regex_match(token, floatingPoint))
        {
            // convert to double using lexical_cast<> and add to array
        }
    }
David G
  • 94,763
  • 41
  • 167
  • 253
0

Thanks for the help everybody - But all this seems a bit advanced for someone of my poor capability! We have been suggested to use the following - but am unsure how you would do this to distinguish between words and numbers:

fstream myfile("data1");
myfile.eof ();
myfile.good ();
myfile.fail ();
myfile.clear ();
myfile.ignore ();
myfile.close ();
myfile.peek ();
Serena
  • 21
  • 1