Aar*_*lar 0 c++ file-io while-loop conditional-statements
我有一个文件:
P 0.5 0.6 0.3
30 300
80 150
160 400
200 150
250 300
T
r 45 0 0
s 0.5 1.5 0 0
t 200 –150
.
.
.
Run Code Online (Sandbox Code Playgroud)
当我读到'P'时,我知道将会有3个花车.接下来是有限数量的X和Y坐标.数字会有所变化,直到达到"T",我必须承认.然后可能会有一个'r','s'或't'后跟一些值.
无论如何我知道如何识别'P'然后接收2个浮点数然后我知道我必须有一个while循环的X和Y坐标,当我到达'T'时它将停止.我不太了解C++使循环停止并识别'T'然后做其他事情.
一个例子来解释将不胜感激.提前致谢!
我会告诉你我认为这是正确的C++方式.首先定义一个用于表示第一行和执行IO的类:
struct FirstLine
{
double x, y, z;
friend std::istream & operator>>(std::istream & is, FirstLine & data)
{
std::string line, ignore;
std::getline(is, line);
std::istringstream iss(line);
iss >> ignore >> data.x >> data.y >> data.z;
assert(ignore == "P" && iss);
return is;
}
friend std::ostream & operator<<(std::ostream & os, FirstLine const & data)
{
return os << "P " << data.x << " " << data.y << " " << data.z;
}
};
Run Code Online (Sandbox Code Playgroud)
我在assert中添加了一些基本的错误检查,你可能想要在你的最终程序中更强大一些.
现在是中间线的一个类:
struct MiddleLine
{
double x, y;
friend std::istream & operator>>(std::istream & is, MiddleLine & data)
{
std::string line;
std::getline(is, line);
if(line == "T")
is.clear(std::ios::failbit);
else
{
int n = sscanf(line.c_str(), "%lf %lf", &data.x, &data.y);
assert(n == 2);
}
return is;
}
friend std::ostream & operator<<(std::ostream & os, MiddleLine const & data)
{
return os << data.x << " " << data.y;
}
};
Run Code Online (Sandbox Code Playgroud)
当我们到达中间线的部分的末尾时,我们应该遇到"T".在这种情况下,我们引发流的失败位,这将告诉客户端没有更多的中间行要读取.
最后一行为最后一行:
struct LastLine
{
std::string identifier; // r, s or t
std::vector<double> values;
friend std::istream & operator>>(std::istream & is, LastLine & data)
{
std::string line;
std::getline(is, line);
std::istringstream iss(line);
iss >> data.identifier;
assert(data.identifier == "r" || data.identifier == "s"
|| data.identifier == "t");
std::copy(std::istream_iterator<double>(iss),
std::istream_iterator<double>(), std::back_inserter(data.values));
return is;
}
friend std::ostream & operator<<(std::ostream & os, LastLine const & data)
{
os << data.identifier << " ";
std::copy(data.values.begin(), data.values.end(),
std::ostream_iterator<double>(os, " "));
return os;
}
};
Run Code Online (Sandbox Code Playgroud)
最后一行更复杂,因为我们不知道每个都有多少值,所以我们只读尽可能多的值.
那是棘手的部分.现在我们的主要功能只是读取第一行,然后是未知数量的中间行,最后是未知数量的最后一行:
int main()
{
std::string const data = "P 0.5 0.6 0.3\n
"30 300\n"
"80 150\n"
"160 400\n"
"200 150\n"
"250 300\n"
"T\n"
"r 45 0 0\n"
"s 0.5 1.5 0 0\n"
"t 200 –150";
std::istringstream iss(data);
FirstLine first_line;
iss >> first_line;
std::vector<MiddleLine> middle_lines;
std::copy(std::istream_iterator<MiddleLine>(iss),
std::istream_iterator<MiddleLine>(),
std::back_inserter(middle_lines));
iss.clear();
std::vector<LastLine> last_lines;
std::copy(std::istream_iterator<LastLine>(iss),
std::istream_iterator<LastLine>(),
std::back_inserter(last_lines));
assert(iss.eof());
std::cout << first_line << "\n";
std::copy(middle_lines.begin(), middle_lines.end(),
std::ostream_iterator<MiddleLine>(std::cout, "\n"));
std::copy(last_lines.begin(), last_lines.end(),
std::ostream_iterator<LastLine>(std::cout, "\n"));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是你得到的输出::
P 0.5 0.6 0.3
30 300
80 150
160 400
200 150
250 300
r 45 0 0
s 45 0 0 0.5 1.5 0 0
t 45 0 0 0.5 1.5 0 0 200
Run Code Online (Sandbox Code Playgroud)
我已经使用字符串作为我的数据源,但您可能想要从文件中读取.
就是这样,你可以看到我没有写一个循环.