JohnP
JohnP

Reputation: 109

Read part of string to integer array

I was writing a C++ program to manipulate a text file. A part of the task involves searching the text file for a particular "search string" and store a part of it as an integer array.

I wrote the following code:

ifstream myoutfile;                      
myoutfile.open (outputfile.c_str());    // filename is passed as a user input
string search="SEARCH STRING"           // search string
while (getline(myoutfile, line))
{
     if (line.find(search) != string::npos)
     {
           cout << line[54] << line[55] << line[56] << endl;  
     }
}

the thing is I want to read 54th 55th and 56th characters of the line into an array as a single integer. (Lets say that 54th charcter is '1' 55th is '2' and 56th is '6'. I would like to read it as number 126 into an array. Is it possible to do that inside this loop, or I have to save this into a file and write a separate section to read contents of the file into array. I was wondering whether anybody can help.

Upvotes: 1

Views: 250

Answers (3)

billz
billz

Reputation: 45410

You could use std::stringstream and std::string::substr to get sub-string out and convert to int. Also could use std::atoi

#include <sstream>

int i = 0;
std::istringstream ss(line.substr(54, 3));
ss >> i;

Or

#include <cstdlib>
int b = std::atoi(line.substr(54, 3).c_str());

Upvotes: 5

James Kanze
James Kanze

Reputation: 153919

The usual solution here is std::istringstream, but it does require more work than other posters seem to suggest:

std::istringstream parser( line.substr( 54, 3 ) );
parser >> i;
if ( !parser || parser.get() != EOF ) {
    //  Error.
} else {
    //  No error, you can use i...
}

If you have C++11, you can use std::stoi, but at first look, it seems even more complex:

size_t end = 0;
try {
    i = std::stoi( line.substr( 54, 3 ), &end );
} catch ( std::runtime_error const& ) {
    //  No numeric characters present...
    //  end remains 0...
} 
if ( end != 3 ) {
    //  Error, either string wasn't long enough, or
    //  contained some non-numeric.
} else {
    //  No error, you can use i...
}

On the other hand, by catching std::invalide_argument and std::out_of_range separately, you can distingish the type of error.

Or, of course, you can just use strtol directly:

char tmp1[4] = {};
line.copy( tmp1, 3, 54 );
char* end;
errno = 0;
long tmp2 = strtol( tmp1, &end, 10 );
if ( errno != 0 || end != tmp1 + 3 || tmp2 > INT_MAX || tmp2 < INT_MIN ) {
    //  Error...
} else {
    i = tmp2;
    //  No error, you can use i...
}

All things considered, I think I prefer the first method (but the last will probably be significantly faster).

Upvotes: 0

No Idea For Name
No Idea For Name

Reputation: 11577

if it is just the 54 till 56 chars exactly you can do:

int x = (line[54] - '0') * 100 +(line[55] - '0') * 10 +(line[56] - '0') ;

the line[54] - '0' part convert the char sign number to the number it is.

Upvotes: 3

Related Questions