简体   繁体   English

从文件中读取数据并将每行存储在数组中?

[英]Reading data from a file and storing each line in an array?

I have a file with lines of integers. 我有一个整数行的文件。 I want to read each line into a slot in my array. 我想将每一行读入我的数组中的一个插槽。 I have the code below, but it does not work. 我有下面的代码,但它不起作用。 I'm not sure if I'm on the right track. 我不确定我是否走在正确的轨道上。

void Read_Save() {
    ifstream in;
    int arr[100];
    string line;
    in.open("file.txt");
    while (in.peek() != EOF)
    {
        getline(in, line, '\n');
        strcpy(arr, line.c_str());
    }
    in.clear(); in.close();
}

There are several ways to parse the integer value out of the string. 有几种方法可以解析字符串中的整数值。

First, let's fix your loop: 首先,让我们修复你的循环:

int pos = 0;
while( std::getline(in, line) && pos < 100 )
{
    int value = 0;

    // Insert chosen parsing method here

    arr[pos++] = value;
}

Here is a non-exhaustive list of common options: 以下是常见选项的非详尽列表:

  1. Use std::strtol 使用std::strtol

     // Will return 0 on error (indistinguishable from parsing actual 0) value = std::strtol( line.c_str(), nullptr, 10 ); 
  2. Use std::stoi 使用std::stoi

     // Will throw exception on error value = std::stoi( line ); 
  3. Build a std::istringstream and read from it: 构建一个std::istringstream并从中读取:

     std::istringstream iss( line ); iss >> value; if( !iss ) { // Failed to parse value. } 
  4. Use std::sscanf 使用std::sscanf

     if( 1 != std::sscanf( line.c_str(), "%d", &value ) ) { // Failed to parse value. } 

Now, note the bounds-test on the loop checking pos < 100 . 现在,注意循环检查pos < 100的边界测试。 This is because your array has a storage limit. 这是因为您的阵列具有存储限制。 Actually, you have also overridden the global one with a local one in Read_Save , thus hiding it with a smaller array that will be lost when the function finishes. 实际上,你还使用Read_Save的本地数据覆盖了全局的Read_Save ,从而将它隐藏在一个较小的数组中,该数组在函数完成时将丢失。

You can have an arbitrary-sized "array" (not actually an array) using other container types provided by the standard library. 您可以使用标准库提供的其他容器类型来拥有任意大小的“数组”(实际上不是数组)。 Useful ones that provide random access are std::vector and std::deque . 提供随机访问的有用的是std::vectorstd::deque Let's use the vector and change the definition of Read_Save to be a bit more useful: 让我们使用向量并将Read_Save的定义更改为更有用:

std::vector<int> Read_Save( std::istream & in )
{
    std::vector<int> values;
    std::string line;

    for( int line_number = 1; getline( in, line ); line_number++ )
    {
        try {
            int value = std::stoi( line );
            values.push_back( value );
        }
        catch( std::bad_alloc & e )
        {
            std::cerr << "Error (line " << line_number << "): Out of memory!" << std::endl;
            throw e;
        }
        catch( std::exception & e)
        {
            std::cerr << "Error (line " << line_number << "): " << e.what() << std::endl;
        }
    }

    return values;
}

And finally, the call becomes: 最后,电话变为:

std::ifstream in( "file.txt" );
std::vector<int> values = Read_Save( in );

You cannot use strcpy() to convert a string to an integer. 您不能使用strcpy()将字符串转换为整数。 You can use std::strtol() or std::stoi() , or even a std::istringstream , eg: 你可以使用std::strtol()std::stoi() ,甚至是std::istringstream ,例如:

int arr[1000];

void Read_Save() {
    ifstream in;
    string line;
    in.open("file.txt");
    int index = 0;
    while ((index < 1000) && (getline(in, line)))
    {
        if (istringstream(line) >> arr[index])
            ++index;
    }
}

The best thing to do in your case is to use std::vector . 在你的情况下,最好的办法是使用std::vector The code would look like this: 代码如下所示:

void Read_Save()
{
    std::ifstream in("file.txt");
    int value;
    std::vector<int> arr;

    while (in >> value)
        arr.push_back(value);

    for(int i(0); i < arr.size(); i++)
        std::cout << arr[i] << ", ";

    std::cout << std::endl;
    in.close();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM