1

I have a txt file with numbers with this format 12345678-A plus some random numbers and text in between. I need to read the file and save only the 8 digit integrers to an array. How do I do it?

Current code I have, works if there are numbers only:

const int MAX = 1000;

ifstream file("file.txt");

int data;
int index = 0;
int bigdata[MAX];

while (!file.eof() && index < MAX)
{
    file >> data;
    if (data > 20000000 && data < 90000000)
    {
        bigdata[index] = data;
        index++;
    }
}

Sample of input text:

48251182-D 6,5 6
49315945-F 7 3
45647536-I 3,5 3
45652122-H 7 6,5
77751157-L 2 2,5
75106729-S 2 5
77789857-B 4 3 3,5 3
59932967-V 4 8,5
39533235-Q 8 8,5
45013275-A 5 2
48053435-Y 6 8
48015522-N 3,5 4
48015515-T
48118362-B 7,5 3,5
39931759-Q 5,5 3
39941188-D 3,5 1,5
39143874-I 3,5 4
48281181-O 6,5 6
Christian Callau
  • 960
  • 6
  • 11

3 Answers3

5

If all you need is to strip out the first number in each line then you can use the stream's operator >> to read in the integer part and then use std::getline to consume the rest of the line. Using

std::vector<int> data;
ifstream fin("file.txt");
int number;
std::string eater;

while (fin >> number) // get first 8 digit number.  stops at the '-'
{
    data.push_back(number);
    std::getline(fin, eater); // consume the rest of the line
    //now we are on the next line
}

// now data has all of the numbers that start each line.
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
2

You need this:

...
#include <string>
...   
string line;
while (getline(file, line))   // read the whole line
{
   int data = stol(line);     // get number at start of line (stops
                              // automatically at the '-' sign

   // data is the 8 digit number
   // process data here...
   ...
}
...
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • Thank you! That's exactly what I was looking for, I had trouble making stol / stoi work in codeblocks and I had to use atoi(line.c_str()); instead. Worked nicely. – Christian Callau Apr 15 '16 at 00:01
-1

One solution to this problem would be to read the stream character by character and search for 8-digit numbers:

static const int MAX = 1000;

int index = 0;
int bigdata[MAX];

int value = 0;
int digits = 0;

for (auto c = file.get(); c != EOF 0; c = file.get())
{
    if (c >= '0' && c <= '9')
    {
        value = (digits ? (value * 10) : 0) + (c - '0');
        ++digits;
        if (digits == 8)
        {
            if (index < MAX)
                bigdata[index++] = value;
            digits = 0;
        }
    } else
    {
        digits = 0;
    }
}

The code reads byte by byte and builds an integer number if decimal digits are read. If the digit count reaches 8 the number is stored and the integer number buffer is reset. The integer number buffer is reset immediatly if the character read is not a decimal digit.

istream.get() returns EOF if reading past the end of the file so no need for a call to the .eof() member function.

Please note that this code stores all 8-digit numbers. You have to add another test if you need only numbers in the range 20000000..90000000.

If your lines are always starting with an 8-digit number followed by a minus then you could use this simple solution which I would recommend because of improved readability.

std::string buffer;
std::vector<int> target;
while (std::getline(file, buffer))
    target.push_back(atoi(buffer.c_str()));

But this solution does not check for the presence of a valid number and simply stores 0 for each line not starting with a number.

Andreas H.
  • 1,757
  • 12
  • 24
  • 1
    Far too complicated. Let the libraries to the dirty work. – Jabberwocky Apr 14 '16 at 13:24
  • I misread the question and wrote code to read any 8-digit number from the file. My answer now contains also a simple solution to read numbers from the beginning of each line. – Andreas H. Apr 15 '16 at 07:02
  • @AndreasH. I had to process a file with the numbers not being at the beginning of each line and your first suggestion worked perfectly, thank you! – Christian Callau Apr 17 '16 at 08:21