簡體   English   中英

使用stringstream標記字符串,其中最后一個字符是定界符

[英]Tokenize a string with stringstream where the last char is the delimiter

我正在從文件中讀取數據,並將其放入字符串令牌中,如下所示:

std::vector<Mytype> mytypes;
std::ifstream file("file.csv");
std::string line;
while (std::getline(file, line)){
    std::stringstream lineSs(line);
    std::vector<std::string> tokens;
    std::string token;
    while (std::getline(lineSs, token, ',')){
        tokens.push_back(token);
    }
    Mytype mytype(tokens[0], tokens[1], tokens[2], tokens[3]);
    mytypes.push_back(mytype);
}

顯然,這是一種非常標准的方法。 但是,數據沒有NULL值,相反,此時該數據將為空。 我的意思是數據可能看起來像這樣:

id0,1,2,3
id1,,2,
id2,,,3

中線的情況給我帶來了問題,因為盡管應該有一個空字符串,但是在“ 2”之后沒有任何東西被壓回到我的令牌向量中。 然后,當我嘗試創建Mytype實例時遇到一些out_of_range問​​題。

到目前為止,我一直在檢查每行的最后一個字符是否為逗號,如果是,請在行末添加一個空格。 但是我想知道是否有更好的方法可以做到這一點。

謝謝。

區別在於第2行在最后一次調用getline()之前具有!lineSs.eof()。 因此,如果getline()返回false,就應該停止循環( 注意 :這並不是getline()返回false的真正原因,而是當流轉換為bool時流為false); 相反,一旦lineSs.eof()返回true,就將其停止。

這是對程序的修改,它顯示了這個想法:

int main() {
    std::string line;
    while (std::getline(std::cin, line)){
        std::stringstream lineSs(line);
        std::vector<std::string> tokens;
        do {
            std::string token;
            std::getline(lineSs, token, ',');
            tokens.push_back(token);
            std::cout << "'" << token << "' " << lineSs.eof() << ' ' << lineSs.fail() << std::endl;
        } while(!lineSs.eof());
        std::cout << tokens.size() << std::endl;
    }
}

它將在最后一行為“ 1,2,3”顯示“ 3”,為“ 1,2,3”顯示“ 4”。

如果行以逗號結尾,則向向量中添加null字符串的一種簡單方法是在創建mytype之前先進行檢查。 如果添加

if (line.back() == ',')
    tokens.push_back("");

在您的內部while循環之后,如果您結束時將為空列,則這將為tokens添加一個空字符串。

所以

while (std::getline(lineSs, token, ',')){
    tokens.push_back(token);
}

while (std::getline(lineSs, token, ',')){
    tokens.push_back(token);
}
if (line.back() == ',')
    tokens.push_back("");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM