C++ 读取文本文件以显示给多个联系人

C++ 读取文本文件以显示给多个联系人,c++,xml,loops,C++,Xml,Loops,我必须读取名为“address.xml”的文件,该文件包含: <?xml version="1.0"?> <address_book> <contact> <name>George Clooney</name> <street>1042 El Camino Real</street> <city>Beverly Hills</city>

我必须读取名为“address.xml”的文件,该文件包含:

<?xml version="1.0"?>
<address_book>
    <contact>
        <name>George Clooney</name>
        <street>1042 El Camino Real</street>
        <city>Beverly Hills</city>
        <state>CA</state>
        <zip>90214</zip>
       </contact>

乔治·克鲁尼
1042埃尔卡米诺皇家酒店
比佛利山庄
加利福尼亚州
90214
等等,有多个联系人。只需要显示那些与城市棕榈谷。我已经定义了联系人的每个元素,但是当我试图在Palmdale中显示这些元素时,它只列出一个联系人(文本文档中的最后一个)。我是否需要使用一个循环来显示它们

void test2() {
    ifstream fin;
    string row, name, street, city, state, zip;
    int start, end;
    fin.open("address.xml");
    if (fin.fail()) {
        cout << "There was an error opening the file...";
        exit(1);
    }

while (getline(fin, row)) {

    if ((start = row.find("<name>")) != string::npos) {
        start = row.find(">");
        end = row.find("</name>");
        name = row.substr(start + 1, end - start - 1);
    }
    if ((start = row.find("<street>")) != string::npos) {
        start = row.find(">");
        end = row.find("</street>");
        street = row.substr(start + 1, end - start - 1);
    }
    if ((start = row.find("<city>")) != string::npos) {
        start = row.find(">");
        end = row.find("</city>");
        city = row.substr(start + 1, end - start - 1);
    }
    if ((start = row.find("<state>")) != string::npos) {
        start = row.find(">");
        end = row.find("</state>");
        state = row.substr(start + 1, end - start - 1);
    }
    if ((start = row.find("<zip>")) != string::npos) {
        start = row.find(">");
        end = row.find("</zip>");
        zip = row.substr(start + 1, end - start - 1);
    }
}

if (city == "Palmdale") {
    cout << name << endl << street << endl
        << city << endl << state << endl << zip << endl;
}
fin.close();
}
void test2(){
流鳍;
字符串行、名称、街道、城市、州、邮政编码;
int开始,结束;
fin.open(“address.xml”);
if(fin.fail()){
库特
  • if(city==“Palmdale”){…}
    仅应用于最后一条记录。您需要在循环内打印
  • 您最好使用XML解析器库,因为您的程序可能会因为合法的XML而失败。
    • 它不会丢弃前导空格和尾随空格
    • 它假定开始标记、值和结束标记之间没有换行符
    • 它引用没有上下文的行,而不是作为
      contact
      节点,例如,如果从一个元素中省略city,它将使用前一个元素的city
  • 你的
    if(city==“Palmdale”){…}
    不在任何循环中,因此它只会在所有数据处理完毕后运行一次。相反,您应该在每次获得所有数据时都运行它。例如,如果您确定您的模式将完全保持这种状态,则可以在读取
    元素时假设您的记录已完成。或者更好的是,当
    元素关闭。请尝试以下操作:

    while (getline(fin, row)) {
    
        if ((start = row.find("<name>")) != string::npos) {
            start = row.find(">");
            end = row.find("</name>");
            name = row.substr(start + 1, end - start - 1);
        }
        if ((start = row.find("<street>")) != string::npos) {
            start = row.find(">");
            end = row.find("</street>");
            street = row.substr(start + 1, end - start - 1);
        }
        if ((start = row.find("<city>")) != string::npos) {
            start = row.find(">");
            end = row.find("</city>");
            city = row.substr(start + 1, end - start - 1);
        }
        if ((start = row.find("<state>")) != string::npos) {
            start = row.find(">");
            end = row.find("</state>");
            state = row.substr(start + 1, end - start - 1);
        }
        if ((start = row.find("<zip>")) != string::npos) {
            start = row.find(">");
            end = row.find("</zip>");
            zip = row.substr(start + 1, end - start - 1);
        }
        if ((row.find("</contact>")) != string::npos) {
            if (city == "Palmdale") {
                cout << name << endl << street << endl
                << city << endl << state << endl << zip << endl;
            }
        }
    }
    
    
    fin.close();
    }
    

    注意:我不属于tinyxml,但在过去使用过它。

    在我看来,您每次都在迭代整个文件并覆盖名称/街道/城市/州/邮政编码地址,然后只在最后打印。如果将If条件放在while循环中,它可能会起作用。when row.find(“”)如何为每条记录存储它?您正在存储
    名称
    以及其他
    if((start=row.find)(
    调用并假设一旦它点击
    ,所有字段都将被读取。此时,它将打印所有字段(如果
    城市
    Palmdale
    )。然后
    if((start=row.find>)(
    对于下一个
    联系人,
    元素将再次覆盖字符串。
    #include <iostream>
    #include <string>
    #include "tinyxml2.h"
    #include "tinyxml2.cpp"
    
    int main() {
        tinyxml2::XMLDocument doc;
        doc.LoadFile("address.xml");
        tinyxml2::XMLElement* book = doc.FirstChildElement("address_book");
    
        for (tinyxml2::XMLElement* contact = book->FirstChildElement("contact");
            contact != NULL; contact = contact->NextSiblingElement())
        {
            std::string name = contact->FirstChildElement("name")->GetText();
            std::string street = contact->FirstChildElement("street")->GetText();
            std::string city = contact->FirstChildElement("city")->GetText();
            std::string state = contact->FirstChildElement("state")->GetText();
            std::string zip = contact->FirstChildElement("zip")->GetText();
    
            if (city == "Palmdale") {
                std::cout << name << std::endl << street << std::endl
                    << city << std::endl << state << std::endl << zip << std::endl;
            }
        }
    }