tags:

views:

1610

answers:

5

Hi,

I've read a file, and stored its contents into a string array.

I need to change some numerical values, interpreted as characters by the compiler.

The file is of the format: ABCDE,EFGHIJ KLMNOPQRS,45.58867,122.59750

I've searched and studied but haven't got onto anything too comprehensive.

If someone can please tell me how to do this I would be very glad.

And I'm not allowed to use strtod; I think it's a C function and my program needs to be strictly C++ only.

Here is my code that I've developed so far:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iomanip>
#include <cstdlib>
#include <sstream>


using namespace std;


int main()
{

    string usrFileStr,
    fileStr = "airNames.txt",  // declaring an obj string literal
    sBuffer,
    sLine = "";

    istringstream iStrStrm;

    int lineCount = 1;
    int nStart;


    fstream inFile;                  // declaring a fstream obj
    // cout is the name of the output stream
    cout << "Enter a file: ";
    cin >> usrFileStr;


    inFile.open( usrFileStr.c_str(), ios::in ); 
    // at this point the file is open and we may parse the contents of it


    while ( getline ( inFile, sBuffer ) && !inFile.eof() )
    {
          nStart = -1 ;
          cout << "First Str " << lineCount << " (";
          for ( int x = nStart + 1; x < sBuffer.length(); x++ )
          {
              if ( sBuffer[ x ] == ',' )
              {
                   nStart = x;
                   break;
                   }
              cout << sBuffer[ x ];


          }
          cout << ") ";
          for ( int x = nStart + 1; x < sBuffer.length(); x++ )
          {

              if ( sBuffer[ x ] == ',' )
              {    
                   nStart = x;
                   break;
                   }
              cout << sBuffer[ x ];
          }
          cout << " (Second Str: "; // lattitude loop


          for ( int x = nStart + 1; x < sBuffer.length(); x++ )
          {
              if ( sBuffer[ x ] == ',' )
              {
                   nStart = x;
                   break;
                   }
              cout << sBuffer[ x ];         
          }

          cout << ", Third String: ";
          for ( int x = nStart + 1; x < sBuffer.length(); x++ )
          {
              if ( sBuffer[ x ] == ',' )
              {
                   nStart = x;
                   break;
                   }
              cout << sBuffer[ x ];
          }
          cout << ") \n";
          lineCount++;
    }


    cout << "There are a Total of: " <<  lineCount << " line(s) in the file."
    << endl;


    inFile.clear();           // clear the file of any errors
    inFile.close();  // at this point we are done with the file and may close it

    fgetc( stdin );
    return 0;
}

I've tried to only read two digits after the decimal, but I only get one character. My first attempt was with static_cast but that was way off. And a istringstream variable won't let its argument be an array. I don't know what to do..

+3  A: 

stringstream

Learn to love it. Not istringstream, since you want to get output from it. Something like:

getline ( inFile, sBuffer );
stringstream myStream(sBuffer);
string first, second, third;
char comma;

myStream >> first;  
myStream >> second;
myStream >> third;

float value1, value2;
myStream >> value1;
myStream >> value2;

Also I would advise you check to make sure the file actually opens.

Whaledawg
That will read the whole line into first!
Martin York
No it wouldn't, but it still wasn't correct because by default iostream doesn't consider a comma a delimiter. Added a loop to replace commas with spaces.
Whaledawg
+1  A: 

You want stringstream, as suggested, but...

As an aside, it's silly to neglect C functions in the context of a C++ program. Most OS functions are going to be exported as C functions, and C++ itself is generally (always?) compiled down to the equivalent of C code anyway, so there's nothing that sticking to only C++ constructs/functions buys you. By all means use the higher-level abstractions and methodologies provided by C++ when appropriate, but if you try to avoid all C-linkage functions, you're hurting yourself for no good reason. Use what works; real programming is hard enough without jumping through self-imposed limitations.

Of course, the above is only applicable to real world programming; homework assignments and such may be the exception. :)

Nick
C++ is hardly ever compiled into C code in anymore. This was true for the very first version of CFront written by stroustrup but even for that compiler it is no longer the case. most compilers compile directly to machine code.
shoosh
Other than that, avoiding strtok just because it's "not pure C++" is a no brainer.
shoosh
Yeah; that's why I said the equivalent of C code. As in: you can write everything you can express in C++ in C if you want (although it might be messy); they are functionally equivalent. That's what I was trying to express.
Nick
A: 

Hi,

You can also try to use boost regex, See: http://www.boost.org/doc/libs/1_37_0/libs/regex/doc/html/boost_regex/captures.html

This way you can add a reqex for the ',' char and capture the values within, even validate them maybe...

Good luck !

RoccoD
A: 

Using string.find() could get rid of some of your loops (it probably just does them internally, but no need to reinvent the wheel). You can use a stringstream to convert the number strings into floats or doubles.

Mongoose
A: 

Use boost spirit (http://www.boost.org/doc/libs/1_37_0/libs/spirit/classic/index.html). Takes a moment to get used to but is very powerful and useful if you get to know it.