C++ifstream只读整数

C++ ifstream read only integers

本文关键字:整数 只读 C++ifstream      更新时间:2023-10-16

我有一个txt文件,里面有12345678-a格式的数字,还有一些随机数字和介于两者之间的文本。我需要读取文件并只将8位整数保存到数组中。我该怎么做?

当前代码我有,工作如果只有数字:

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++;
    }
}

输入文本示例:

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

如果您只需要去掉每行中的第一个数字,那么您可以使用流的operator >>读取整数部分,然后使用std::getline消耗该行的其余部分。使用

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.

您需要这个:

...
#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...
   ...
}
...

这个问题的一个解决方案是逐个字符读取流并搜索8位数:

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;
    }
}

该代码逐字节读取,如果读取十进制数字,则构建一个整数。如果数字计数达到8,则存储该数字并重置整数缓冲器。如果读取的字符不是十进制数字,则会立即重置整数缓冲区。

如果读取超过文件末尾,istream.get()将返回EOF,因此无需调用.of()成员函数。

请注意,此代码存储所有8位数字。如果你只需要20000000到90000000之间的数字,你必须添加另一个测试。

如果你的行总是以一个8位数的数字开头,后面跟着一个负数,那么你可以使用这个简单的解决方案,因为可读性更好,我建议你使用这个解决方案。

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

但这个解决方案不检查是否存在有效的数字,只是为每一行存储0,而不是以数字开头。