从2d整数数组中的文件中读取

时间:2019-04-01 17:52:46

标签: c++

我是C ++编码的新手,我需要读取具有以下结构的文件:

8
1 0 0 0 1
1 1 1 0 0
1 1 0 0 0
1 1 1 1 0
5

我需要将数字读入2个不同的int变量(8和5)中,其余的读入2d int数组中。

我到目前为止所拥有的:

#include<fstream>
#include<iostream>
#include<conio.h>

using namespace std;

ifstream fin("f.in");
ofstream gout("g.out");

int a[30][30], n, x;

int main()
{
    fin>>n;

    for(i=1; i<=n; i++)
        for(j=1; j<=n; j++)
        {
            fin>>a[i][j];

        }
    fin>>x; c[1]=x; s[x]=1;
//other function call .....

    for(i=1; i<=n; i++)
        gout<<c[i]<<" ";

    return 0;
}

代码正在构建和编译,但是不会从文件中读取。

1 个答案:

答案 0 :(得分:0)

如果您仍然受困,那么请逐步进行操作。

第一个不对文件名进行硬编码。 (并且不要使用 magic-number ,例如,代码中包含的任何数字,而不是为其正确定义常量)。 ifstream fin("f.in");如果要读取另一个文件"f.int2"怎么办?这就是功能参数的用途。对于main(),您有argc可以告诉您给出了多少个参数,还有argv,它是指向每个arg的指针的数组(其后是终止的NULL指针) 。使用它们。例如:

int main (int argc, char **argv) {
...
    if (argc < 2) { /* validate 1-argument available for filename */
        std::cerr << "error: insufficnent input\nusage: " << argv[0]
                << " filename\n";
        return 1;
    }

    std::ifstream fin (argv[1]);    /* open filename given by 1st argument */

注意:,第一个参数值argv[0]始终是正在运行的可执行文件名称,因此您必须检查总共两个参数以确保{{ 1}})

下一步确认,例如,打开文件以供读取

argv[1]

现在让我们开始阅读输入文件,我将其命名为 if (!fin.good()) { /* validate file open for reading */ std::cerr << "error: file open failed '" << argv[1] << "'.\n"; return 1; } ,然后将其放置在2dintarr+stuff.txt子目录中,例如

示例输入文件

dat

$ cat dat/2dintarr+stuff.txt 8 1 0 0 0 1 1 1 1 0 0 1 1 0 0 0 1 1 1 1 0 5 "+stuff"8,与您要存储的2D值数组无关。只需将整行读入5,从该行创建一个8,然后循环并从字符串流读取整数,即可轻松处理5string直到您用完所有要读取的数字为止。如果在用完数字之前只读取一个值,则可以将这些值简单地存储在非数组的某个位置(例如在称为stringstream的向量中)。如果一行中有多个值,则将所有值存储在一个向量中,并将该向量作为一行添加到向量的向量中。

听起来很复杂,但事实并非如此。 C ++提供了容器,使您可以像在数组中那样向其添加和删除值,但是更好的是,这些容器会自动为您管理内存,根据需要分配更多空间,并在没有更多引用指向容器时释放内存。容器。其中的一个容器是notarr,您可以将其视为简单的一维数组。 C ++允许容器包含其他容器。因此,当您需要2D数组时,所需的就是向量的向量。

在您的情况下,您需要一个vector来保存读取的每一行数据,您需要为数组使用向量string的向量,然后需要另一个单个向量来保存{{1} },它不是数组的一部分,称为arr。声明如下:

"+stuff"

现在剩下的就是读取每一行,然后从该行创建一个字符串流,以便您可以循环从该行读取整数,直到用完要读取的数字为止。 (您不能仅在循环中使用notarr,因为读取iostream会跳过前导空白#include <string> #include <vector> ... std::string line; /* string for reading each line */ std::vector<std::vector <int>> arr; /* vector<vector<int>> (2D arr) */ std::vector<int> notarr; /* vector to hold single values */ 是空白,因此尝试在文件上使用fin >> number;流本身-您永远无法知道行中有多少个值,'\n'只会跳过>>作为空格。

该如何解决?使用>>。基本上,stringstream等效于可用作流的缓冲区。因此,您从文件中读取了一行数据,从文件中创建了一个字符串流,然后循环执行'\n',该循环将在到达字符串流的末尾(即缓冲区)时停止,因为没有其他内容可供您读取了。确定原始行中包含多少个值。 (您将一遍又一遍地使用此技术)

示例:

stringstream

上面,您只需将每一行读入while (ss >> value),创建字符串团队 while (getline (fin, line)) { /* read each remaining data line */ int i; std::vector<int> tmp; /* vector<int> for each line */ std::stringstream ss (line); /* stringstream to read from */ while (ss >> i) /* read int from stringstream */ tmp.push_back(i); /* add to tmp vector */ if (tmp.size() == 1) /* if single value in line */ notarr.push_back(i); /* add value to notarr */ else if (tmp.size() > 1) /* if multiple values in line */ arr.push_back(tmp); /* add tmp vector to arr */ } ,然后使用临时向量line,将每个值加载到临时向量中。完成后,您只需检查ss向量中有多少个元素。如果为tmptmp,则将其添加到向量8中;如果大于一个,则5包含2D数组的一行,因此添加它会notarr。就是这样。

完全将其放入,您可以执行以下操作:

tmp

注意:向量容器提供了arr#include <iostream> #include <fstream> #include <sstream> #include <string> #include <vector> #include <limits> int main (int argc, char **argv) { std::string line; /* string for reading each line */ std::vector<std::vector <int>> arr; /* vector<vector<int>> (2D arr) */ std::vector<int> notarr; /* vector to hold single values */ if (argc < 2) { /* validate 1-argument available for filename */ std::cerr << "error: insufficnent input\nusage: " << argv[0] << " filename\n"; return 1; } std::ifstream fin (argv[1]); /* open filename given by 1st argument */ if (!fin.good()) { /* validate file open for reading */ std::cerr << "error: file open failed '" << argv[1] << "'.\n"; return 1; } while (getline (fin, line)) { /* read each remaining data line */ int i; std::vector<int> tmp; /* vector<int> for each line */ std::stringstream ss (line); /* stringstream to read from */ while (ss >> i) /* read int from stringstream */ tmp.push_back(i); /* add to tmp vector */ if (tmp.size() == 1) /* if single value in line */ notarr.push_back(i); /* add value to notarr */ else if (tmp.size() > 1) /* if multiple values in line */ arr.push_back(tmp); /* add tmp vector to arr */ } std::cout << "2D array of values:\n\n"; for (auto& i : arr) { /* loop over rows */ for (auto& j : i) /* loop over each value in column */ std::cout << " " << j; /* output value */ std::cout << '\n'; /* tidy up with newline */ } std::cout << "\nSingle-values:\n\n"; for (auto& i: notarr) /* output values not part of array */ std::cout << " " << i; std::cout << '\n'; /* tidy up with newline */ } 成员函数,可让您向向量添加值并告诉您其中包含许多元素分别。)

使用/输出示例

.push_back()

仔细检查一下,如果还有其他问题,请告诉我。