C++ 如何避免阅读文本文件中的注释?
目前,我已使用此代码成功地将一些介于0到10之间的随机数写入我的文件(下面只是一些示例代码来演示此问题): 当我从该文件读取数据并输出到另一个文件时,会出现问题:C++ 如何避免阅读文本文件中的注释?,c++,parsing,input,output,readfile,C++,Parsing,Input,Output,Readfile,目前,我已使用此代码成功地将一些介于0到10之间的随机数写入我的文件(下面只是一些示例代码来演示此问题): 当我从该文件读取数据并输出到另一个文件时,会出现问题: int type; while (afile >> type) { if(type == 0) { afile >> .........; .......... } else if(type == 1) {.........}
int type;
while (afile >> type)
{
if(type == 0)
{
afile >> .........;
..........
}
else if(type == 1) {.........}
else if(type == 2) {.........}
}
}
......................................
我的输出文件在第一行之后停止读取,因为它也读取了要处理的无效数据的注释,如果我删除了注释,则一切正常。那么我该如何克服这种情况呢?谢谢。有几种方法可以做到这一点 找到报价后跳过行的其余部分(更快) 基本上,这里要做的是在循环中逐行读取文件。当您点击两个字符“/”时。你可以叫“休息”,然后跳到下一行 一些未经测试的伪代码:
while(line = file.getLine()){
loopChars = sizeof(line);
for(x = 0; x < loopChars; x++) {
char currentChar = line[x];
if(x+1 < loopChars){
char nextChar = line[x+1];
} else {
char nextChar = '';
}
if(nextChar == "/" && currentChar == "/"){
// Go to next line
break;
} else {
// Do your normal processing here
}
}
}
while(line=file.getLine()){
loopChars=sizeof(行);
对于(x=0;x
先删除引号(较慢)
下面是一个从文件中删除引号(一行“/”和多行“/**/”)的解决方案。基本上,在开始读取数字数据之前,您会对正在处理的文件运行此操作
#包括
#包括
使用名称空间std;
int main(){
河流充填;
字符串文件名;
出流孔的直径;
字符c1,c2;
bool-isInsideComment=false;
cout>文件名;
infle.open(filename.c_str());
if(infle.fail()){
你有几个合理的选择:
- 将整行内容读入
std::string
,扫描并删除任何注释,然后从剩下的内容中创建std::istringstream
,并从中提取非注释值
- 在读取值之前,请使用std::ws
和afile.peek()
查看下一个字符是否为'/'
:如果是,请跳过,直到到达换行符
前者是一种在C++中使用的有用的技术(当你想用数据问题报告行数时),看起来像这样:
if (std::ifstream in(filename))
{
std::string line;
while (getline(in, line))
{
std::string::size_type n = line.find("//");
if (n != std::string::npos)
line.erase(n);
std::istringstream iss(line);
int atype;
while (iss >> atype)
...etc...
}
正如我所见,Tony D已经提供了一个合理的答案,但我想我也应该添加一个自己的代码,因为我已经编写并测试了它
下面对于任何一个讲C++的人来说都是很清楚的,它基本上是托尼提出的,但是有一个扭曲——用一行一行的数据,利用<代码> STD::StrugStule,但是也利用了数据OP的二进制性质。数据既有有效的整数,也有注释。r是否为有效整数。因此,在下面的代码中,当无法将数据从流有效转换为整数时,该行的其余部分将被视为注释。编辑:……实际上,虽然这是一个有点有效的解决方案,但我修改了代码,使其包含一种更为合理的方法—跳过注释的方法(用
#
或/
表示,以显示两种方法)但仍然让我们决定对格式错误的值执行什么操作。这不允许45fubar
作为45
传递,然后是坏fubar
,这是前面代码的问题,但允许正确解释45//comment
我仍然认为直接删掉\/\/.*?
是一个更好的方法。不过,这个答案的要点是有点不同
#包括
#包括
#包括
#包括
#包括
#包括
#包括
无效写入(std::ostream&output,int行){
对于(int i=0;i 输出您需要检查它正在处理的字符\数据是否等于“\”。如果发生这种情况,它将立即中断或进入下一行您使用的!infle.eof()
不可靠…它只能保证在尝试读取文件结尾后设置,因此如果infle.get(c1)
读取一个字符,并且文件中没有其他字符,它仍然没有设置eof
,并将继续执行infle.get(c2);
操作失败,在尝试将c2
与“*”和“/”进行比较之前,保持c2
不变(可能未初始化)(可能未定义的行为)很可能调用outfile.put(c2);
.Yep,这可能会导致软件出现错误,当你看到而(!stream.eof())
时,你应该开始非常小心了。;)很好的建议Xupicor.BTW,如果解析数字后流不在eof()
,你可以使用ss.clear();
然后ss.get()='/'&&ss.get()=='/'
以确保有评论……感谢您的努力,但我现在还不熟悉vector,因为我只是一个新手。我将来会回到您的解决方案,因为它看起来非常复杂!:)@Resolution:std::vector
只是标准模板库(STL)中的一个标准容器你可以把它当作一个动态分配内存的数组,代码中的所有内容都符合标准C++,虽然有些是C++ 11专用的,比如尼斯for for循环。)@ Tyyd你找到的解决方案<代码> //<代码>,擦除后面的内容,我几乎要做的是——除非一个包含它的字符串这可能是一个格式良好的数据,但它看起来不像。我这样写的全部目的是利用数据的性质,并成为一个与你的答案稍有不同的答案。;)不过……请稍后查看编辑。
while(line = file.getLine()){
loopChars = sizeof(line);
for(x = 0; x < loopChars; x++) {
char currentChar = line[x];
if(x+1 < loopChars){
char nextChar = line[x+1];
} else {
char nextChar = '';
}
if(nextChar == "/" && currentChar == "/"){
// Go to next line
break;
} else {
// Do your normal processing here
}
}
}
#include <iostream>
#include <fstream>
using namespace std;
int main (){
ifstream infile;
string filename;
ofstream outfile;
char c1, c2;
bool isInsideComment = false;
cout << "Please input file name (to remove comments from): ";
cin >> filename;
infile.open (filename.c_str());
if (infile.fail()) {
cout << "nInvaild file name.n";
return 1;
}
outfile.open(("out_"+filename).c_str());
infile.get (c1);
while (!infile.eof()) {
if ((c1 == '/') && (!isInsideComment)) {
infile.get (c2);
if (c2 == '*')
isInsideComment = true;
else if ((c1 == '/') && (c2 == '/'))
isInsideComment = true;
else {
outfile.put (c1);
outfile.put (c2);
}
}
else if ( (c1 == '*') && isInsideComment) {
infile.get (c2);
if (c2 == '/')
isInsideComment = false;
else if ((c1 == 'n') && isInsideComment)
isInsideComment = false;
}
else if (!isInsideComment)
outfile.put (c1);
infile.get (c1);
}
infile.close();
outfile.close();
}
if (std::ifstream in(filename))
{
std::string line;
while (getline(in, line))
{
std::string::size_type n = line.find("//");
if (n != std::string::npos)
line.erase(n);
std::istringstream iss(line);
int atype;
while (iss >> atype)
...etc...
}
$ ./test.exe < data > data
50 44 92 43 97
26 32 54
30 91
93 4
$ cat data
50 44 92 43 97 // 5 numbers
26 32 54 // 3 numbers
30 91 // 2 numbers
93 4 // 2 numbers
$ ./test.exe < data2 > dump
Unexpected symbol: 'i91'
Unexpected symbol: '4i'
Unexpected symbol: 'lol'
Unexpected symbol: 'numbers'
50 44 92 43 97
26 32 54
30
93 3 2
7337
7337
$ cat data2
50 44 92 43 97 // 5 numbers
26 32 54 # 3 numbers
30 i91 // 2 numbers
93 4i lol 3 2 numbers
7337//test comment
7337#test comment 2