我是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;
}
代码正在构建和编译,但是不会从文件中读取。
答案 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
,然后循环并从字符串流读取整数,即可轻松处理5
和string
直到您用完所有要读取的数字为止。如果在用完数字之前只读取一个值,则可以将这些值简单地存储在非数组的某个位置(例如在称为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
向量中有多少个元素。如果为tmp
或tmp
,则将其添加到向量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()
仔细检查一下,如果还有其他问题,请告诉我。