Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 用逗号将字符串拆分_C++_C++17 - Fatal编程技术网

C++ 用逗号将字符串拆分

C++ 用逗号将字符串拆分,c++,c++17,C++,C++17,我试图用逗号分割一个字符串并填充一个向量。当前代码适用于第一个索引,但是,对于下一个迭代,迭代器忽略逗号,但理解后面的那个。有人能告诉我为什么吗 getline(file,last_line); string Last_l = string(last_line); cout<< "String Lastline worked "<< Last_l <<endl; int end = 0; int start = 0;

我试图用逗号分割一个字符串并填充一个向量。当前代码适用于第一个索引,但是,对于下一个迭代,迭代器忽略逗号,但理解后面的那个。有人能告诉我为什么吗

    getline(file,last_line);
    string Last_l = string(last_line);
    cout<< "String Lastline worked "<< Last_l <<endl;
    int end = 0;
    int start = 0;
    vector<string> linetest{};

    for(char &ii : Last_l){
        if( ii != ','){
            end++;
        }
        else{
            linetest.push_back(Last_l.substr(start,end));
//            Disp(linetest);
            cout<< Last_l.substr(start,end) <<endl;
            end++;
            start = end;
        }

    }
getline(文件,最后一行);
字符串最后一行=字符串(最后一行);

根据您的代码,我认为您误解了传递给的参数。请注意,第二个索引是第一个参数后的字符计数,而不是子字符串的结束索引

记住这一点,在else条件下,而不是:

end++;  // increment end index
start = end;  // reset start index
您需要执行以下操作:

start = end + 1;  // reset start index
end = 0;  // reset count of chars
另外,不要忘记在循环结束后,在最后一个逗号后添加额外的字符串:

linetest.push_back(Last_l.substr(start + end));  // all the remaining chars
以下是完整的片段:

for(char &ii : Last_l){
        if( ii != ','){
            end++;
        }
        else{
            linetest.push_back(Last_l.substr(start,end));
            start = end + 1;
            end = 0;
        }
}

linetest.push_back(Last_l.substr(start + end));
和一份工作

如果您将
end
重命名为
count
,这将更有意义


另外,请避免使用命名空间std,因为这被认为是不好的做法。

因此,已经给出了一个很好的答案

我想展示一些替代方案

将字符串拆分为标记是一项非常古老的任务。有许多可用的解决方案。它们都有不同的属性。有些很难理解,有些很难开发,有些更复杂,更慢或更快或更灵活

替代品

  • 手工制作,就像你的一样,可能很难开发并且容易出错。看看你的问题
  • 使用老式的
    std::strok
    函数。可能不安全。也许不应该再使用了
  • std::getline
    。最常用的实现。但实际上是一种“误用”,并没有那么灵活
  • 使用专门为此目的开发的专用现代功能,最灵活、最适合STL环境和算法环境。但是慢一点
  • 请参阅一段代码中的4个示例

    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>
    #include <regex>
    #include <algorithm>
    #include <iterator>
    #include <cstring>
    #include <forward_list>
    #include <deque>
    
    using Container = std::vector<std::string>;
    std::regex delimiter{ "," };
    
    
    int main() {
    
        // Some function to print the contents of an STL container
        auto print = [](const auto& container) -> void { std::copy(container.begin(), container.end(),
            std::ostream_iterator<std::decay<decltype(*container.begin())>::type>(std::cout, " ")); std::cout << '\n'; };
    
        // Example 1:   Handcrafted -------------------------------------------------------------------------
        {
            // Our string that we want to split
            std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
            Container c{};
    
            // Search for comma, then take the part and add to the result
            for (size_t i{ 0U }, startpos{ 0U }; i <= stringToSplit.size(); ++i) {
    
                // So, if there is a comma or the end of the string
                if ((stringToSplit[i] == ',') || (i == (stringToSplit.size()))) {
    
                    // Copy substring
                    c.push_back(stringToSplit.substr(startpos, i - startpos));
                    startpos = i + 1;
                }
            }
            print(c);
        }
    
        // Example 2:   Using very old strtok function ----------------------------------------------------------
        {
            // Our string that we want to split
            std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
            Container c{};
    
            // Split string into parts in a simple for loop
    #pragma warning(suppress : 4996)
            for (char* token = std::strtok(const_cast<char*>(stringToSplit.data()), ","); token != nullptr; token = std::strtok(nullptr, ",")) {
                c.push_back(token);
            }
    
            print(c);
        }
    
        // Example 3:   Very often used std::getline with additional istringstream ------------------------------------------------
        {
            // Our string that we want to split
            std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
            Container c{};
    
            // Put string in an std::istringstream
            std::istringstream iss{ stringToSplit };
    
            // Extract string parts in simple for loop
            for (std::string part{}; std::getline(iss, part, ','); c.push_back(part))
                ;
    
            print(c);
        }
    
        // Example 4:   Most flexible iterator solution  ------------------------------------------------
    
        {
            // Our string that we want to split
            std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
    
    
            Container c(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});
            //
            // Everything done already with range constructor. No additional code needed.
            //
    
            print(c);
    
    
            // Works also with other containers in the same way
            std::forward_list<std::string> c2(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});
    
            print(c2);
    
            // And works with algorithms
            std::deque<std::string> c3{};
            std::copy(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {}, std::back_inserter(c3));
    
            print(c3);
        }
        return 0;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    使用Container=std::vector;
    std::regex分隔符{“,”};
    int main(){
    //打印STL容器内容的函数
    自动打印=[](const auto&container)->void{std::copy(container.begin(),container.end(),
    
    std::ostream_迭代器(std::cout,“”);std::cout请检查以下内容以获得简明的解决方案。这是否回答了您的问题?