C++ 捕获文本文件行中的错误、跳过和报告

C++ 捕获文本文件行中的错误、跳过和报告,c++,string,whitespace,split,C++,String,Whitespace,Split,我有一个我需要阅读的文本文件,每一行都是一个IP,一个URL,最后是一个日期,都用空格隔开。我想获得分配给类对象“Visitor”的相应变量的每一条信息。我有一个数组来存储它们。我的问题是,当我试图浏览文本文件时,这些行……我总是在所有文本之间获得空白 class Visitors{ public: string IP; string URL; string dateAccessed; }; int main(){ Visitors hits[N]; string filename,

我有一个我需要阅读的文本文件,每一行都是一个IP,一个URL,最后是一个日期,都用空格隔开。我想获得分配给类对象“Visitor”的相应变量的每一条信息。我有一个数组来存储它们。我的问题是,当我试图浏览文本文件时,这些行……我总是在所有文本之间获得空白

class Visitors{

public:
string IP;
string URL;
string dateAccessed;

};

int main(){

Visitors hits[N];

string filename, theLine;
ifstream infile;

cout << "Enter file name (with extension):" << flush;

while(true){

    string infilename;
    getline(cin, infilename);
    infile.open(infilename.c_str());
    if(infile) break;

    cout << "Invalid file. Please enter valid file name: " << flush;

}

cout << "\n";

while(!infile.eof()){

    getline(infile, theLine);

    istringstream iss(theLine);

    do{

        string ip;
        string url;
        string date;

        iss >> ip;
        iss >> url;
        iss >> date;

        if(ip != "\n"){

             cout << "The IP: " << ip << endl;

        }

        if(url != "\n"){

             cout << "The URL: " << url << endl;

        }

        if(date != "\n"){

            cout << "The DA: " << date << endl;

        }


    }while(iss);

}

return 0;

}
编辑:好的,我已经知道了如何遍历每一行,将其分解,并相应地将字符串添加到对象数组中类变量中它所属的位置。现在的问题是我想检查每行的每个字符串是否有错误(例如,日期是不可能的,或者IP中的一个数字是256等等)。一旦发现错误,我想跳到下一行,做同样的检查,如果一切正常,它将在数组中的正确位置初始化类变量。这是我的代码,以了解我正在尝试做什么

#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

#define N 50

using namespace std;

class Visitors{

public:
string IP;
string URL;
string dateAccessed;

};

int main(){

Visitors hits[N];

string infilename, filename, ip, url, date;
ifstream infile;

int i = 0;

cout << "Enter file name (with extension):" << flush;

while(true){

    infilename = "";
    getline(cin, infilename);
    infile.open(infilename.c_str());
    if(infile) break;

    cout << "Invalid file. Please enter valid file name: " << flush;

}

cout << "Loading " << infilename << "..." << endl;;
cout << "\n";

while(infile.good()){

    string line;
    getline(infile, line);
    stringstream ss(line);

    if(ss >> ip >> url >> date){

        cout << "The IP: " << ip << endl;
        hits[i].IP = ip;

        cout << "The URL: " << url << endl;
        hits[i].URL = url;

        cout << "The DA: " << date << endl;
        hits[i].dateAccessed = date;

        i++;

    }

    else{

        cerr << "error" << std::endl;

    }

    /*

    if(ip.length() > 15 || ip.length() < 7){

        cout << "Found a record with an invalid IP format (not XXX.XXX.XXX.XXX)...ignoring entry";

    }

    //if(any of the numbers in the IP address are great then 255)
        //INVALID IP...IGNORE ENTRY

    else{

        cout << "The IP: " << ip << endl;
        hits[i].IP = ip;

    }

    //if(url doesnt start with www. or doesnt end with .xxx)
        //INVALID URL...IGNORE ENTRY

    else{

        cout << "The URL: " << url << endl;
        hits[i].URL = url;

    }

    //if(date.length != 10)
        //INVALID DATE FORMAT...IGNORE ENTRY

    //if(first 2 numbers in date arent between 01 and 12
         //OR if second 2 numbers arent between 01 and 31 depending on month OR etc.)
         //INVALID....IGNORE ENTRY

    else{

        cout << "The DA: " << date << endl;
        hits[i].dateAccessed = date;

    }

    i++;*/

}

return 0;

}
#包括
#包括
#包括
#包括
#定义N 50
使用名称空间std;
班级访客{
公众:
字符串IP;
字符串URL;
已访问的字符串;
};
int main(){
访客点击[N];
字符串填充名、文件名、ip、url、日期;
河流充填;
int i=0;

cout您不需要stringstream和内部循环:

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
int main(){
    std::string filename, theLine;
    std::ifstream infile;
    std::cout << "Enter file name (with extension):" << std::flush;
    while(true){
        std::string infilename;
        getline(std::cin, infilename);
        infile.open(infilename.c_str());
        if(infile) break;
        std::cout << "Invalid file. Please enter valid file name: " 
            << std::flush;
    }

    std::cout << "\n";
    std::string ip, url, date;
    while(infile.good()) {
        std::string line;
        getline(infile, line);
        std::stringstream ss(line);
        if (ss >> ip >> url >> date) {
            std::cout << "The IP: " << ip << std::endl;
            std::cout << "The URL: " << url << std::endl;
            std::cout << "The DA: " << date << std::endl;
        } else {
            std::cerr << "error" << std::endl;
        }
    }

    return 0;
}
#包括
#包括
#包括
#包括
int main(){
std::字符串文件名,行;
std::ifstream-infle;
标准::cout>日期){

std::cout您不需要stringstream和内部循环:

#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
int main(){
    std::string filename, theLine;
    std::ifstream infile;
    std::cout << "Enter file name (with extension):" << std::flush;
    while(true){
        std::string infilename;
        getline(std::cin, infilename);
        infile.open(infilename.c_str());
        if(infile) break;
        std::cout << "Invalid file. Please enter valid file name: " 
            << std::flush;
    }

    std::cout << "\n";
    std::string ip, url, date;
    while(infile.good()) {
        std::string line;
        getline(infile, line);
        std::stringstream ss(line);
        if (ss >> ip >> url >> date) {
            std::cout << "The IP: " << ip << std::endl;
            std::cout << "The URL: " << url << std::endl;
            std::cout << "The DA: " << date << std::endl;
        } else {
            std::cerr << "error" << std::endl;
        }
    }

    return 0;
}
#包括
#包括
#包括
#包括
int main(){
std::字符串文件名,行;
std::ifstream-infle;
标准::cout>日期){
std::cout
cout
cout最简单的解决方案(就您必须更改多少代码而言)是只与
进行比较,而不是与
”\n“
进行比较:

if(ip!=”{cout最简单的解决方案(就您必须更改多少代码而言)是只与
进行比较,而不是与
“\n”
进行比较:


if(ip!=“”){为什么是内部循环?你能在一行中有更多的条目吗?不,每行一个条目。我这样做的目的是希望通过列表,然后在这些行被分割成子字符串时,通过这些行,然后获取每一个并分配它们。为什么是内部循环?你能在一行中有更多的条目吗?不,每行一个条目。是的它希望通过列表,然后通过行,因为它们被分割成子字符串,然后得到每一个并分配它们。哦,伙计,我有空格,尝试了新的行字符。没有想过尝试那个。谢谢。哦,伙计,我有空格,尝试了新的行字符。没有想过尝试那个。谢谢。怎么做如果发现错误,我可以跳过这一行并转到下一组吗?@Sherifftwinkie,更新了答案。为此,您确实需要stringstream:)在将数据添加到我的类对象数组的类变量时,如何显示特定于错误的消息并交换行而不是数组位置。我会立即更新我的OP,以便更好地解释我的意图。如果你想看的话,我已经用我的意图更新了我的OP。感谢你到目前为止的帮助,非常感谢。将
if(ss>>ip>>url>>date)
更改为
if((ss>>ip>>url>>date)&&isValidIP(ip)&&isvalidul(url)&isvalidul(date))
并实现这些验证功能。这就足够了。如果发现错误,我如何跳过该行并转到下一组?@Sherifftwinkie,更新了答案。为此,您确实需要stringstream:)在将数据添加到类va时,显示错误特定的消息并交换行而不是数组位置呢我的类对象数组的变量。我会及时更新我的OP以更好地解释我的意图。如果您想看一看,我已经用我的意图更新了我的OP。感谢您到目前为止的帮助,非常感谢。将
if(ss>>ip>>url>>date)
更改为
if((ss>>ip>>url>>date)&isValidIP(ip)&isvalidul(url)&&isValidDate(date))
并实现这些验证功能。这就足够了。
cout << "Enter file name (with extension):" << flush;

string infilename;
getline(cin, infilename);
infile.open(infilename.c_str());

// You don't need to loop here. You can just exit the program. 
// But this is optional.
if(!infile) {
   cout << "Invalid file. Please enter valid file name: " << endl;
   exit(1);
}

cout << endl;

int line_nr = 1;
while(getline(infile, theLine)){
    istringstream iss(theLine);
    string ip;
    string url;
    string date;

    // A line is expected to have ip url date format. Otherwise it is error.
    if(iss >> ip >> url >> date)
        cout << "The IP: " << ip << endl;
        cout << "The URL: " << url << endl;
        cout << "The DA: " << date << endl;

     }

     else {
        cout << "Error reading data on line: " << line_nr << flush;
        break;
     }

     ++line_nr;

}
if (ip   != "") { cout << "The IP: "  << ip   << endl; }
if (url  != "") { cout << "The URL: " << url  << endl; }
if (date != "") { cout << "The DA: "  << date << endl; }