如何在函数中逐行返回字符串?

时间:2017-06-01 06:57:20

标签: c++

我正在读取一个文本文件,其中包含由新行分隔的整数。像这样。

5006179359870233335
13649319959095080120
17557656355642819359
15239379993672357891
3900144417965865322
12715826487550005702

从这个文件中,我想访问循环中的每个整数并将其与另一个整数进行比较,以匹配这两个整数。在函数File_read()中,我可以打印整数。但我想要的是在函数外部通过整数获取整数。例如,在main方法中,如果有一个名为x的整数,我想检查x是否等于我的文本文件中的一个整数。

string File_read() {
    std::ifstream my_file("H:\\Sanduni_projects\\testing\\test.txt", 
    std::ifstream::binary);
    if (my_file) {
        string line;

        for (int i = 0; i < 25; i++){
            getline(my_file, line);
            //cout << line << endl;
            return line;
        }

        if (my_file)
            std::cout << "all characters read successfully."<<endl;

        my_file.close();
    }
    return 0;
}

5 个答案:

答案 0 :(得分:1)

永远不要在循环内无条件返回。

您无条件地从循环内部返回。这会导致调用者退出循环并在第一次迭代期间从函数返回。

for (int i = 0; i < 25; i++){
    getline(my_file, line);
    return line; // <-- Return from function (rest of iterations unreachable). Bad.
}

无需重新发明内容

使用标准库将数字例如读入容器std::vector

std::vector<unsigned long long> v{std::istream_iterator<unsigned long long>{my_file},
                                  std::istream_iterator<unsigned long long>{}};

注意适合大数字所需的unsigned long long的值类型(你在这里推~64位)。

查找匹配

使用例如std::find查找已解析数字之间可能的匹配。

auto key = 15239379993672357891ull;

if (auto it = std::find(std::begin(v), std::end(v), key); it != std::end(v)) {
    std::cout << "Key found at line " << std::distance(std::begin(v), it) + 1 << std::endl;
}

在这里,我使用C++1z if(init; condition) statement将迭代器it的范围限制在if语句中。当然,它是可选的。

Live example

答案 1 :(得分:0)

目前,您只是返回第一个数字(作为std::string而不是数字)。如果删除循环中的return语句,当然可以打印每个语句。以下是File_read函数的略微修改版本,该版本将返回包含所有数字的std::vector<unsigned long long>。然后,您可以在例如main函数中使用此向量进行处理。

std::vector<unsigned long long> File_read()
{
    std::vector<unsigned long long> numbers;
    std::ifstream my_file("H:\\Sanduni_projects\\testing\\test.txt"); // Text files are not 'binany', i.e., removed std::ifstream::binary
    if (my_file)
    {
        std::string line;

        for (int i = 0; i < 25; i++)
        {
            std::getline(my_file, line);
            numbers.push_back(std::stoull(line));
        }

        if (my_file)
        {
            std::cout << "all characters read successfully." << std::endl;
        }

//        my_file.close(); // Do not do this manually
    }
    return numbers;
}

用法示例:

int main()
{
    unsigned long long x = /* some number */;

    // Read all the numbers
    std::vector<unsigned long long> vl = File_read();

    // Run through all the numbers
    for (unsigned long long y : vl)
    {
        // Check if any of the numbers are equal to x
        if (x == y)
        {
            // There is a match...
            // Do stuff
        }
    }
}

更新

long无法保留这些数字,但unsigned long long就足够了。

答案 2 :(得分:0)

std::vector<long> File_read(){
    vector<long> numbers;
    ifstream my_file("H:\\Sanduni_projects\\testing\\test.txt", 
     std::ifstream::binary);
    if (my_file) {
        string line;

        for (int i = 0; i < frames_sec; i++){
            getline(my_file, line);
            numbers.push_back(std::stol(line));
        }

        if (my_file)
            std::cout << "all characters read successfully." << endl;
        else
            std::cout << "error: only " << my_file.gcount() << " could be read" << endl;
        my_file.close();

    }
    else{
        cout << "File can not be opened" << endl;
    }
    return numbers;
}

答案 3 :(得分:0)

虽然有人给出了正确的答案,但我想分享我的代码。

#include <memory>
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
#define MAX_SIZE 4096
class FileRead
{
public:
    FileRead(string path) :_file(path)
    {
        Reset();
    }
    void Reset()
    {
        memset(_buff, 0, MAX_SIZE);
    }
    string ReadLine()
    {
        if (!_file.is_open())
        {
            cout << "error open file" << endl;  
            return "";
        }
        if (!_file.eof())
        {
            Reset();
            _file.getline(_buff,MAX_SIZE);
            return string(_buff);
        }
        else
        {
            cout << "read file finished." << endl;
            return "";
        }       
    }

private:
    ifstream _file;
    string _line;
    char _buff[MAX_SIZE];
};

int _tmain(int argc, _TCHAR* argv[])
{   
    FileRead fr("H:\\Sanduni_projects\\testing\\test.txt");
    string line;
    while (!(line = fr.ReadLine()).empty())
    {
        //do some compare..
    }
    return 0;    
}

答案 4 :(得分:0)

其他答案对于返回的工作方式是正确的,但something表示您认为返回的行为方式。

using string_coro = boost::coroutines::asymmetric_coroutine<std::string>

void File_read(string_coro::push_type & yield) {
    std::ifstream my_file("H:\\Sanduni_projects\\testing\\test.txt", std::ifstream::binary);
    if (my_file) {
        string line;

        for (int i = 0; i < 25; i++){
            getline(my_file, line);
            yield (line);
        }

        if (my_file)
            std::cout << "all characters read successfully." << std::endl;

        my_file.close();
    }
}

使用哪个

string_coro::pull_type(File_read) strings;
for (const std::string & s : strings)
    std::cout << s << endl;