簡體   English   中英

從文件讀取后將分號分隔的整數存儲到數組中

[英]Store semicolon-separated integers into array after reading from file

我的數據來自一個如下所示的文本文件:

...
[timestamp]
1096757
[logtime]
2019-10-22 15:29:17.435
[scan]
32;39;36;39;39;39;39;42;42;44;46;48;48;49;51;52;54;54;54;53;50;50;50;54;54;56;56;56;56;57;57;56;56;58;56;56;57;58;58;59;58;59;60;61;60;61;61;60;60;61;61;62;63;63;63;63;63;61;61;61;61;61;61;62;62;62;62;62;62;64;68;64;64;63;61;61;61;60;61;60;62;60;60;59;60;59;59;57;62;57;57;57;57;57;58;63;63;63;63;63;61;61;62;59;59;61;62;61;63;64;63;61;63;61;61;61;63;63;63;59;62;62;59;60;60;60;57;60;61;61;61;61;61;61;56;56;56;57;59;61;61;59;57;57;57;57;59;61;59;61;60;60;60;63;63;63;63;63;63;61;61;61;62;62;62;62;65;69;69;68;68;70;68;72;72;72;71;72;72;73;72;73;73;73;73;73;73;73;73;72;71;69;69;69;69;70;73;70;68;68;68;66;65;66;66;64;64;64;62;60;57;57;57;53;53;53;51;50;47;46;45;44;44;44;44;43;42;43;43;44;45;45;45;45;
[timestamp]
1096858
[logtime]
2019-10-22 15:29:17.532
[scan]
41;38;38;38;38;38;40;40;41;42;46;47;49;49;48;49;50;49;51;52;52;52;52;53;53;53;57;58;58;58;58;57;57;57;56;56;59;56;57;58;58;58;58;58;61;63;59;60;61;60;60;61;61;61;61;61;61;62;62;60;60;60;60;60;60;61;61;61;62;63;63;62;62;62;62;64;65;65;64;59;59;59;60;60;61;61;60;63;63;62;59;58;58;58;59;61;61;62;64;64;64;63;63;60;60;63;64;64;64;63;63;60;58;58;58;59;59;59;59;59;59;59;61;60;60;60;60;60;60;60;60;61;61;59;59;58;58;59;62;62;62;59;59;59;59;59;61;61;61;61;61;60;60;62;62;62;62;62;62;62;62;64;64;66;66;69;69;70;69;69;70;71;71;72;72;72;72;72;73;74;74;71;71;71;70;71;71;71;71;72;72;76;72;71;70;71;70;71;70;66;65;65;64;63;64;60;60;60;
[timestamp]
...

我試圖在單詞[scan]之后從數據中獲取前 10 個數字。 我設法讓我的代碼找到數據的行號,但我找不到將數據(每次掃描的前 10 個)放入 int 數組的方法。

我使用了一些我找到的代碼,但它並沒有像我預期的那樣工作。

我正在嘗試將數據保存為如下所示。 第一個數組包含:

32
39
36
39
39
39
39
42
42
44

第二個數組包含以下內容:

41
38
38
38
38
38
40
40
41
42

正如您在問題中所寫,您能夠在輸入文件中找到包含所需數據的行。 所以我假設您能夠閱讀該行並將其存儲為std::string 以下示例顯示如何從std::string中提取前 10 個數字,用分號分隔並將其添加到std::vector<int>

#include <iostream>
#include <string>
#include <vector>

int main()
{
    std::string str = "32;39;36;39;39;39;39;42;42;44;46;48;48;49;51;52;54;";
    std::vector<int> token_list;
    std::string::size_type start_pos = 0;
    std::string::size_type pos = 0;

    while ((token_list.size() < 10) && ((pos = str.find(";", start_pos)) != std::string::npos))
    {
        token_list.push_back(std::stoi(str.substr(start_pos, pos - start_pos)));
        // Set next start position for search behind found semicolon
        start_pos = pos+1;
    }

    // Print extracted data
    for (size_t i = 0; i < token_list.size(); i++)
    {
        std::cout << token_list[i] << std::endl;
    }

    return 0;
}

如果您想使用特殊模式將字符串拆分為子字符串,則這稱為標記化。 這是一個非常古老的機制,甚至在 C 中也有一個 function strtok將字符串拆分為令牌。

在 C++ 中還有一個可用的算法,尤其是與容器類合作時。

這就是所謂的std::sregex_token_iterator 這里 這會遍歷std::string並返回標記。

因此,您應該使用特定且專用的功能。

下一個用於將 n 數據從一個容器復制到另一個容器的專用 function 是std::copy_n

這樣,整個任務將由一個班輪完成。

從字符串數據到任何數字格式的轉換也可以通過專用的 function std::transfrom transfrom 來完成。

並且 output 也從向量復制到std::cout

請看下面的簡單示例:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
#include <regex>

int main() {

    // The source values
    std::string source{ "32;39;36;39;39;39;39;42;42;44;46;48;48;49;51;52;54;" };

    // Here we will store the result
    std::vector<std::string> destination{}; // As string
    std::vector<int> data{};                // Int, or whatever else you want

    // This is the separator betwenn the numbers
    std::regex separator{ ";" };

    // One-liner to copy 10 sub strings to the destination array
    std::copy_n(std::sregex_token_iterator(source.begin(), source.end(), separator, -1), 10, std::back_inserter(destination));

    // Convert ot ints (or whatever)
    std::transform(destination.begin(), destination.end(), std::back_inserter(data), [](const std::string& s) { return std::stoi(s); });

    // And show result on std::cout
    std::copy(data.begin(), data.end(), std::ostream_iterator<int>(std::cout, "\n"));

    return 0;
}

請注意:您當然可以直接將目標數據復制到std::cout 用戶不會在屏幕上看到差異。 但是如果你想做一些進一步的計算,那么你需要轉換。

而且, std::transform也可以直接寫入std::cout 如下所示:

    std::transform(destination.begin(), destination.end(), std::ostream_iterator<int>(std::cout, "\n"), [](const std::string & s) { return std::stoi(s); });

請注意現代 C++ 算法的美妙之處。 C++20 還有更多功能。

暫無
暫無

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

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