【问题标题】:How to convert a string containing multiple numbers to ints and store it in a vector如何将包含多个数字的字符串转换为整数并将其存储在向量中
【发布时间】:2020-01-05 06:43:40
【问题描述】:

我正在编写一个从文件中读取数据的程序。

.txt 文件如下所示:

文字,数字,:5,3,5

文字、数字、:1、3、7、8

我成功提取了“文本”和“数字”,但是当我遇到:“5,3,5”之后的数字时,我真的卡住了。

我需要将这些数字更改为整数并将它们添加到整数向量中,所以我去掉了逗号,然后尝试使用 stoi 将它们转换为整数,但是,stoi 只是“提取”第一个数字,在这种情况下,只有 5 和 1,这是我尝试过的:

while(getline(file, line)){
   stringstream ss(line);
   getline(ss, text, ',');
   getline (ss, nums, ':');
   getline (ss, numList, ',' );
   replace(numList.begin(), numList.end(), ',' , ' ');
   vec.push_back(stoi(numList));

   randomStruct str = {text, nums, numList};

   randomStructVec.push_back(str);


}

打印向量的元素时,我需要输出如下所示:

5 3 5

1 3 7 8

我得到的是:

5

1

有时我也会得到重复的数字: 5

1111

5555

11

我需要一种方法让 stoi 函数将这一行字符串中的所有数字转换为整数,并将它们存储在整数的 vec 中。

任何帮助,将不胜感激。

【问题讨论】:

标签: c++ string file


【解决方案1】:

How do I tokenize a string 上查看我使用String Toolkit Library 的解决方案

这是您的案例的配对版本:

#include <iostream>
#include <vector>
#include <string>
#include <strtk.hpp>  //String Toolkit Library

const char *whitespace  = " \t\r\n\f";
const char *whitespace_and_punctuation  = " \t\r\n\f;,=";

int main()
{

  // parsing a string into a vector of integers with  separators
  // of spaces and punctuation

       std::string s("3; 4, 4, 8,-1");
       std::vector<int> values;
       if( strtk::parse( s, whitespace_and_punctuation, values ) )
       {
           for(size_t i = 0; i < values.size(); ++i )
            std::cout << values[i] << std::endl;
       }

    return 0;
}

您会注意到将值转换为整数向量。 该库仅是标题。该库非常快,可以处理您需要对字符串和解析进行的大部分操作。

【讨论】:

    【解决方案2】:

    您的代码中存在太主要的问题。


    首先getline (ss, numList, ',' ); 将停在列表的第一个值上。实际上,当您的列表是 5,3,5 时,getline (ss, numList, ','); 将读取 5 然后 , 所以它会停止。此时,numValue == "5"

    这很容易解决:只需删除分隔符字符,即getline(ss, numList);。使用这个,numValue == "5,3,5"


    好吧,现在你拥有了所有的价值。您将 ',' 替换为 ' ' 以分隔您的号码。好,numList = "5 3 5"

    然后是您的第二个错误:vec.push_back(stoi(numList));stoi(numList) 返回一个 int 并且无法通过空格字符。所以它只会转换第一个 5 并返回它。你永远不会得到其他数字,因为你甚至不做一个循环。

    这是我的解决方案:将您的字符串转换为字符串流并使用&gt;&gt; 运算符

    std::stringstream numStream(numList);
    int value;
    while(numList >> value)
        vec.push_back(value);
    

    所以我们最终得到了您的最终代码(我删除了stds,因为您似乎在代码中的某处写了using namespace std

    struct randomStruct
    {
       string txt,
       string nb, 
       vector<int> data
    }
    // -------
    while(getline(file, line)){
       stringstream ss(line);
       getline(ss, text, ',');
       getline (ss, nums, ':');
       getline (ss, numList);
       replace(numList.begin(), numList.end(), ',' , ' ');
       stringstream numStream(numList);
       int value;
       while(numStream >> value)
          vec.push_back(value);
    
       randomStruct str = {text, nums, vec};
    
       randomStructVec.push_back(str);
       vec.clear();
    }
    
    // Accessing and printing data
    for (auto str : randomStructVec)
    {
       for (auto i : str.data)
       {
          cout << i << " ";
       }
       cout << endl;
    }
    

    【讨论】:

    • 嗨,伙计,我在尝试编译时遇到了这个奇怪的错误:“错误:使用已删除的函数 'std::stringstream::basic_stringstream(const std::stringstream &)',在线自动numStream = stringstream(numList); 无论如何感谢您的回复!我越来越近了!
    • @Hugs 可能是auto 语法引起的,尝试删除该行并改用stringstream numStream(numList); 来初始化numStream
    • 您的格式化数据存储在vec(类型为vector&lt;int&gt;)中。 NumList 是getline(ss, numList); 的结果,第一行应该是" 5 3 5",第二行应该是" 1 3 7 8" ......我想知道:你需要将值存储在vector&lt;int&gt; 中还是你只需要打印到cout ?
    • 我编辑了我的答案,以便您查看应该是什么 randomStruct 以及如何打印您的数据。注意我也改了randomStruct str = {text, nums, vec};
    • @Hugs 当然,我忘了在每次迭代结束时清除向量。在randomStructVec.push_back(str); 之后添加vec.clear();(我正在编辑)
    【解决方案3】:

    在此函数中使用此函数stoi_(),如果该字符串包含0-9 范围内的字符,我会将字符串转换为数字,否则创建一个新字符串并重复此过程,直到到达字符串末尾。要处理负数,您必须再添加一个条件。

    vector<int> stoi_(string s){
        vector<int>ans;
        int i = 0;
        int n =s.length();
        while(i<n){
            string temp = ""; // current number 
    
           if(s[i]=='-' && (i+1<n && (s[i+1]>='0' && s[i+1]<='9'))){ // handle -ve numbers
               temp = temp + s[i];
               i++;
           }
            while(i<n && s[i]>='0' && s[i]<='9'){ // if current character is number append it into cur number
                temp = temp + s[i];
                i++;
            }
            if(temp.length()>0){
                ans.push_back(stoi(temp)); // here using stoi() for simplicity 
            }
            else{
                i++;
            }
        }
        return ans;
    }
    

    【讨论】:

    • 当你改变他的整个功能时,欢迎解释你的工作
    猜你喜欢
    • 2010-11-22
    • 2022-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 2011-10-31
    相关资源
    最近更新 更多