특정 길이의 줄을 읽고 구문 분석하고 싶습니다. 그들을 구문 분석하기 위해 예외를 사용하여 특정 잘못된 입력을 처리하지만 오류가 발생할 때마다 버퍼가 잘못된 입력으로 채워지고 다음 getline 명령은 파일에 여전히 유효한 입력이 있어도 그 안에 횡설수설을 넣습니다.
내 코드는 다음과 같습니다.
( 파일이 유효하지 않은 경우 읽은 inStream
유형 istream
이므로 cin
)
char buffer[MAX_LINE_LENGTH];
string line;
while (inStream.getline(buffer,MAX_LINE_LENGTH)) {
line=string(buffer);
try {
parse(line, inStream, outStream);
}
catch(const DoneError& e){
outStream<<e.what();
return 0;
}
catch(const MyException& e) {
outStream<<e.what();
}
//invalid_argument or out_of_range at stod & stoi
catch (const logic_error& e) {
outStream<<BadParameterExeption().what();
}
catch(const exception& e){
outStream<<e.what();
}
}
처음으로 parse
(이미 catch 블록에 있음) 예외 buffer
가 원래 내용이 buffer
아닌 정크로 채워지고 루프의 다음 반복도 입력이 아닌 정크로 채워집니다 . 나는 catch 블록을 사용 clear()
하고 시도했지만 ignore(MAX_LINE_LENGTH, '\n')
도움이되지 않았습니다. 어떡해? MAX_LINE_LENGTH 문자를 기껏해야 읽고 한 줄에 그 이상을 얻으면 다음 반복에서 읽을 수 있습니다.
리디렉션이 아닌 파일에서 읽었습니다. 방법은 다음과 같습니다.
ifstream inpFile;
ofstream outFile;
/* I receive the files' names via argv, some are input some are output
* (order is fixed but not the number)
* /.prog outpu1 input1 output2 input2 (and so on)
* degenerated example on how It works:
* for(int i=argc-1; i>0; i-=2){
* inpFile.open(argv[i]);
* if(inpFile.is_open()) return true;
* }
*/
if (!initFiles (argc, argv, inpFile, outFile))
return 1;
istream &inStream = (inpFile.is_open()) ? inpFile : cin;
ostream &outStream = (outFile.is_open()) ? outFile : cout;
더 많은 정보를 제공해야합니다. 다음은 Fedora에서 g ++ 5.1.1로 컴파일 할 때 잘 작동합니다. 분명히, 나는 그것을 컴파일하고 실행하기 위해 누락 된 인프라의 일부를 만들어야했지만 너무 많은 자유를 취했다고 생각하지 않습니다.
#include <iostream>
#include <fstream>
#include <exception>
#include <stdexcept>
#include <string>
using namespace std;
#define min(x, y) (x < y) ? x : y
const int MAX_LINE_LENGTH = 80;
struct DoneError : public exception
{
const char *what() const throw()
{
return "Done Exception";
}
};
struct MyException : public exception
{
const char *what() const throw()
{
return "MyException";
}
};
struct BadParameterExeption : public exception
{
const char *what() const throw()
{
return "Bad Parameter";
}
};
void parse(string l, istream &is, ostream &os)
{
if (l.find("MyException") != string::npos)
throw MyException();
if (l.find("Done") != string::npos)
throw DoneError();
if (l.find("logic") != string::npos)
throw logic_error("You made a logic error");
if (l.find("BadParameter") != string::npos)
throw BadParameterExeption();
}
int main(int argc, char **argv)
{
ifstream inpFile(argv[1]);
ofstream outFile(argv[2]);
istream &inStream = (inpFile.is_open()) ? inpFile : cin;
ostream &outStream = (outFile.is_open()) ? outFile : cout;
char buffer[MAX_LINE_LENGTH];
string line;
try {
while (getline(inStream, line, '\n'))
{
while (line.length() > 0)
{
string smaller = line.substr(0, min(MAX_LINE_LENGTH, line.length()));
line = line.substr(min(MAX_LINE_LENGTH, line.length()));
try {
parse(smaller, inStream, outStream);
}
catch(const DoneError& e){
outStream<<e.what()<<endl;;
return 0;
}
catch(const MyException& e) {
outStream<<e.what()<<endl;;
}
//invalid_argument or out_of_range at stod & stoi
catch (const logic_error& e)
{
outStream<<BadParameterExeption().what()<<endl;;
}
catch(const exception& e){
outStream<<e.what()<<endl;;
}
}
}
}
return 0;
}
궁극적으로 수행하려는 작업에 대해 실제로 설명하지 않았으므로 입력 부분을 처리하는 측면에서 이것을 리팩토링해야 할 것입니다. istream.getline ()은 원시 문자를 처리하며 '이상하게'될 수 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다