在 C++ 中读取输入文件
Reading an input file in C++
我想读取包含以下行的 C++ 输入文件
- numberOfStates
- numberOfSymbols
- numberOfFinalStates
- list of final states (one per line)
- numberOfTransitions
- listOfTransitions (one per line. The transitions include two ints and one char)
重要的是要说每个输入文件中的数字是不同的。我必须为每个文件读取不同数量的行。
这是一个示例输入文件
10
3
1
9
12
0 1 f
0 3 f
1 2 a
2 9 f
3 4 f
3 8 f
4 5 b
5 6 f
6 7 a
8 9 f
如何在读取输入文件时声明每个变量?
这就是我卡住的地方..真的不知道该怎么办
ifstream fin("inputFile.txt");
int numberOfStates;
int numberOfSymbols;
int numberOfFinalStates;
// I'm not sure how to declare the next variables because they will vary in size each time
while (fin >> numberOfStates >> numberOfSymbols >> numberOfFinalStates)
{
cout << numberOfStates << numberOfSymbols << numberOfFinalStates << endl;
}
如果可能的话,我想使用向量。
正在做
while (fin >> name >> var1 >> var2 >> var3)
{
cout << name << var1 << var2 << var3 << endl;
}
你一直在相同的变量上重写,你需要把值放在一个向量中,就像你在问题中说的那样
您还需要检查每个输入是否正确,目前您没有检测到无效输入
当然你需要检查你是否打开了文件
示例:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main()
{
std::ifstream fin("inputFile.txt");
if (!fin.is_open()) {
std::cerr << "cannot open inputFile.txt" << std::endl;
return -1;
}
int numberOfStates, numberOfSymbols, numberOfFinalStates;
if ((! (fin >> numberOfStates >> numberOfSymbols >> numberOfFinalStates))
|| (numberOfStates < 0)
|| (numberOfSymbols < 0)
|| (numberOfFinalStates < 0)) {
std::cerr << "invalid file" << std::endl;
return -1;
}
// final states are int, so memorize them in a vector of int
// because their number is known I can size it rather than
// to 'push_back' each value
std::vector<int> finalStates(numberOfFinalStates);
for (int & ft : finalStates) {
if (! (fin >> ft)) {
std::cerr << "invalid file reading final states" << std::endl;
return -1;
}
}
int numberOfTransitions;
if (!(fin >> numberOfTransitions) || (numberOfTransitions < 0)) {
std::cerr << "invalid file reading the number of transitions" << std::endl;
return -1;
}
// you say a transition contains 2 int and a char,
// I define a structure for
// i1 i2 and c are 'poor' names but I don't know their goal
struct Transition {
int i1, i2;
char c;
};
// the transitions saved in a vector
std::vector<Transition> transitions(numberOfTransitions);
for (Transition & tr : transitions) {
if (!(fin >> tr.i1 >> tr.i2 >> tr.c)) {
std::cerr << "invalid file reading transitions" << std::endl;
return -1;
}
}
// print to check
std::cout << "numberOfStates=" << numberOfStates << std::endl;
std::cout << "numberOfSymbols=" << numberOfSymbols << std::endl;
std::cout << "numberOfFinalStates=" << numberOfFinalStates << "\nfinalStates:";
for (int ft : finalStates)
std::cout << ' ' << ft;
std::cout << std::endl;
std::cout << "numberOfTransitions=" << numberOfTransitions
<< "\ntransitions:" << std::endl;
for (const Transition & tr : transitions)
std::cout << '\t' << tr.i1 << ' ' << tr.i2 << ' ' << tr.c << std::endl;
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ g++ -pedantic -Wextra -Wall a.cc
pi@raspberrypi:/tmp $ cat inputFile.txt
10
3
1
9
12
0 1 f
0 3 f
1 2 a
2 9 f
3 4 f
3 8 f
4 5 b
5 6 f
6 7 a
8 9 f
pi@raspberrypi:/tmp $ ./a.out
invalid file reading transitions
出现错误是因为文件仅包含 10 个转换而不是预期的 12 个,修改文件以预期有 10 个转换:
pi@raspberrypi:/tmp $ ./a.out
numberOfStates=10
numberOfSymbols=3
numberOfFinalStates=1
finalStates: 9
numberOfTransitions=10
transitions:
0 1 f
0 3 f
1 2 a
2 9 f
3 4 f
3 8 f
4 5 b
5 6 f
6 7 a
8 9 f
pi@raspberrypi:/tmp $
如果你有可变数量的东西(在运行时定义)你使用数组:
std::vector<Type> store;
要向矢量添加内容,您可以使用 push_back()
(还有其他方法,但让我们为初学者保持简单)。
store.push_back(value);
要读取多个内容并将它们存储在向量中,只需使用循环即可。
for(int loop = 0; loop < numberOfThings; ++loop) {
Type temp;
fin >> temp;
store.push_back(temp);
}
那么这个神秘的东西是什么Type
?您在这里使用适当的类型名称。对于 "Finale State",它将是一个整数 (int
),但对于 "Transition",它将是一个匹配 (int/int/char
).[=18= 的 class 类型]
std::vector<int> finalState;
for(int loop = 0; loop < finalState; ++loop) {
int nextFinal;
find >> nextFinal;
finalState.push_back(nextFinal);
}
......
std::vector<Transition> Transitions;
... Just like above.
有点晚了,但我还是会 post 展示如何创建自己的流运算符并在创建复合时使用它们 类。
#include <iostream>
#include <fstream>
#include <vector>
struct transition {
// rename the variables into something meaningful
int int1;
int int2;
char a_char;
friend std::istream& operator>>(std::istream&, transition&);
friend std::ostream& operator<<(std::ostream&, const transition&);
};
// input stream function for reading one transition
std::istream& operator>>(std::istream& is, transition& t) {
is >> t.int1 >> t.int2 >> t.a_char;
return is;
}
// output stream function for writing one transition
std::ostream& operator<<(std::ostream& os, const transition& t) {
os << t.int1 << " " << t.int2 << " " << t.a_char;
return os;
}
//-----------------------------------------------------------------------------
struct entity {
int numberOfStates;
int numberOfSymbols;
std::vector<int> finalStates;
std::vector<transition> transitions;
friend std::istream& operator>>(std::istream&, entity&);
friend std::ostream& operator<<(std::ostream&, const entity&);
};
// read one entity from a stream
std::istream& operator>>(std::istream& is, entity& e) {
int numberOfFinalStates, numberOfTransitions;
int value;
if(is >> e.numberOfStates >> e.numberOfSymbols >> numberOfFinalStates) {
// read to value and put it in its vector
while(numberOfFinalStates-- && is >> value) e.finalStates.push_back(value);
if(is >> numberOfTransitions) {
transition ttmp;
// read to the temporary transition and put it in its vector
while(numberOfTransitions-- && is >> ttmp) e.transitions.push_back(ttmp);
// check that we got the number of values we wanted
// and set the failbit if we didn't (should check size() of the vectors
// instead)
if(numberOfFinalStates != -1 || numberOfTransitions != -1)
is.setstate(std::ios_base::failbit);
}
}
return is;
}
// write one entity to a stream
std::ostream& operator<<(std::ostream& os, const entity& e) {
os << e.numberOfStates << "\n" << e.numberOfSymbols << "\n" << e.finalStates.size() << "\n";
for(const int fs : e.finalStates) os << fs << "\n";
os << e.transitions.size() << "\n";
for(const transition& t : e.transitions) os << t << "\n";
return os;
}
//-----------------------------------------------------------------------------
int main() {
std::ifstream fs("inputfile.txt");
if(fs) {
entity e;
// stream the opened file into the entity
if(fs >> e) {
std::cout << "loaded these values:\n";
std::cout << e;
} else {
std::cerr << "failed loading file\n";
}
} else {
std::cerr << "failed opening file\n";
}
}
我想读取包含以下行的 C++ 输入文件
- numberOfStates
- numberOfSymbols
- numberOfFinalStates
- list of final states (one per line)
- numberOfTransitions
- listOfTransitions (one per line. The transitions include two ints and one char)
重要的是要说每个输入文件中的数字是不同的。我必须为每个文件读取不同数量的行。
这是一个示例输入文件
10
3
1
9
12
0 1 f
0 3 f
1 2 a
2 9 f
3 4 f
3 8 f
4 5 b
5 6 f
6 7 a
8 9 f
如何在读取输入文件时声明每个变量?
这就是我卡住的地方..真的不知道该怎么办
ifstream fin("inputFile.txt");
int numberOfStates;
int numberOfSymbols;
int numberOfFinalStates;
// I'm not sure how to declare the next variables because they will vary in size each time
while (fin >> numberOfStates >> numberOfSymbols >> numberOfFinalStates)
{
cout << numberOfStates << numberOfSymbols << numberOfFinalStates << endl;
}
如果可能的话,我想使用向量。
正在做
while (fin >> name >> var1 >> var2 >> var3) { cout << name << var1 << var2 << var3 << endl; }
你一直在相同的变量上重写,你需要把值放在一个向量中,就像你在问题中说的那样
您还需要检查每个输入是否正确,目前您没有检测到无效输入
当然你需要检查你是否打开了文件
示例:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main()
{
std::ifstream fin("inputFile.txt");
if (!fin.is_open()) {
std::cerr << "cannot open inputFile.txt" << std::endl;
return -1;
}
int numberOfStates, numberOfSymbols, numberOfFinalStates;
if ((! (fin >> numberOfStates >> numberOfSymbols >> numberOfFinalStates))
|| (numberOfStates < 0)
|| (numberOfSymbols < 0)
|| (numberOfFinalStates < 0)) {
std::cerr << "invalid file" << std::endl;
return -1;
}
// final states are int, so memorize them in a vector of int
// because their number is known I can size it rather than
// to 'push_back' each value
std::vector<int> finalStates(numberOfFinalStates);
for (int & ft : finalStates) {
if (! (fin >> ft)) {
std::cerr << "invalid file reading final states" << std::endl;
return -1;
}
}
int numberOfTransitions;
if (!(fin >> numberOfTransitions) || (numberOfTransitions < 0)) {
std::cerr << "invalid file reading the number of transitions" << std::endl;
return -1;
}
// you say a transition contains 2 int and a char,
// I define a structure for
// i1 i2 and c are 'poor' names but I don't know their goal
struct Transition {
int i1, i2;
char c;
};
// the transitions saved in a vector
std::vector<Transition> transitions(numberOfTransitions);
for (Transition & tr : transitions) {
if (!(fin >> tr.i1 >> tr.i2 >> tr.c)) {
std::cerr << "invalid file reading transitions" << std::endl;
return -1;
}
}
// print to check
std::cout << "numberOfStates=" << numberOfStates << std::endl;
std::cout << "numberOfSymbols=" << numberOfSymbols << std::endl;
std::cout << "numberOfFinalStates=" << numberOfFinalStates << "\nfinalStates:";
for (int ft : finalStates)
std::cout << ' ' << ft;
std::cout << std::endl;
std::cout << "numberOfTransitions=" << numberOfTransitions
<< "\ntransitions:" << std::endl;
for (const Transition & tr : transitions)
std::cout << '\t' << tr.i1 << ' ' << tr.i2 << ' ' << tr.c << std::endl;
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ g++ -pedantic -Wextra -Wall a.cc
pi@raspberrypi:/tmp $ cat inputFile.txt
10
3
1
9
12
0 1 f
0 3 f
1 2 a
2 9 f
3 4 f
3 8 f
4 5 b
5 6 f
6 7 a
8 9 f
pi@raspberrypi:/tmp $ ./a.out
invalid file reading transitions
出现错误是因为文件仅包含 10 个转换而不是预期的 12 个,修改文件以预期有 10 个转换:
pi@raspberrypi:/tmp $ ./a.out
numberOfStates=10
numberOfSymbols=3
numberOfFinalStates=1
finalStates: 9
numberOfTransitions=10
transitions:
0 1 f
0 3 f
1 2 a
2 9 f
3 4 f
3 8 f
4 5 b
5 6 f
6 7 a
8 9 f
pi@raspberrypi:/tmp $
如果你有可变数量的东西(在运行时定义)你使用数组:
std::vector<Type> store;
要向矢量添加内容,您可以使用 push_back()
(还有其他方法,但让我们为初学者保持简单)。
store.push_back(value);
要读取多个内容并将它们存储在向量中,只需使用循环即可。
for(int loop = 0; loop < numberOfThings; ++loop) {
Type temp;
fin >> temp;
store.push_back(temp);
}
那么这个神秘的东西是什么Type
?您在这里使用适当的类型名称。对于 "Finale State",它将是一个整数 (int
),但对于 "Transition",它将是一个匹配 (int/int/char
).[=18= 的 class 类型]
std::vector<int> finalState;
for(int loop = 0; loop < finalState; ++loop) {
int nextFinal;
find >> nextFinal;
finalState.push_back(nextFinal);
}
......
std::vector<Transition> Transitions;
... Just like above.
有点晚了,但我还是会 post 展示如何创建自己的流运算符并在创建复合时使用它们 类。
#include <iostream>
#include <fstream>
#include <vector>
struct transition {
// rename the variables into something meaningful
int int1;
int int2;
char a_char;
friend std::istream& operator>>(std::istream&, transition&);
friend std::ostream& operator<<(std::ostream&, const transition&);
};
// input stream function for reading one transition
std::istream& operator>>(std::istream& is, transition& t) {
is >> t.int1 >> t.int2 >> t.a_char;
return is;
}
// output stream function for writing one transition
std::ostream& operator<<(std::ostream& os, const transition& t) {
os << t.int1 << " " << t.int2 << " " << t.a_char;
return os;
}
//-----------------------------------------------------------------------------
struct entity {
int numberOfStates;
int numberOfSymbols;
std::vector<int> finalStates;
std::vector<transition> transitions;
friend std::istream& operator>>(std::istream&, entity&);
friend std::ostream& operator<<(std::ostream&, const entity&);
};
// read one entity from a stream
std::istream& operator>>(std::istream& is, entity& e) {
int numberOfFinalStates, numberOfTransitions;
int value;
if(is >> e.numberOfStates >> e.numberOfSymbols >> numberOfFinalStates) {
// read to value and put it in its vector
while(numberOfFinalStates-- && is >> value) e.finalStates.push_back(value);
if(is >> numberOfTransitions) {
transition ttmp;
// read to the temporary transition and put it in its vector
while(numberOfTransitions-- && is >> ttmp) e.transitions.push_back(ttmp);
// check that we got the number of values we wanted
// and set the failbit if we didn't (should check size() of the vectors
// instead)
if(numberOfFinalStates != -1 || numberOfTransitions != -1)
is.setstate(std::ios_base::failbit);
}
}
return is;
}
// write one entity to a stream
std::ostream& operator<<(std::ostream& os, const entity& e) {
os << e.numberOfStates << "\n" << e.numberOfSymbols << "\n" << e.finalStates.size() << "\n";
for(const int fs : e.finalStates) os << fs << "\n";
os << e.transitions.size() << "\n";
for(const transition& t : e.transitions) os << t << "\n";
return os;
}
//-----------------------------------------------------------------------------
int main() {
std::ifstream fs("inputfile.txt");
if(fs) {
entity e;
// stream the opened file into the entity
if(fs >> e) {
std::cout << "loaded these values:\n";
std::cout << e;
} else {
std::cerr << "failed loading file\n";
}
} else {
std::cerr << "failed opening file\n";
}
}