首页 文章

如何读入用户输入的逗号分隔整数?

提问于
浏览
4

我正在编写一个程序,提示用户:

  • 数组大小

  • 要放入数组的值

第一部分很好,我创建一个动态分配的数组(必需),并使其成为用户想要的大小 .

我坚持下一部分 . 期望用户输入一系列由逗号分隔的整数,例如:1,2,3,4,5

如何接受这些整数并将它们放入我动态分配的数组中?我读到默认情况下cin接受由空格分隔的整数,我可以将其更改为逗号吗?

请以最简单的方式解释,我是编程的初学者(对不起!)

编辑:TY非常适合所有答案 . 问题是我们还没有涵盖向量...有没有一种方法只使用我拥有的动态分配的数组?

到目前为止我的功能看起来像这样 . 我在main中创建了一个默认数组 . 我打算将它传递给这个函数,创建新数组,填充它,并更新指针以指向新数组 .

int *fill (int *&array, int *limit) {

cout << "What is the desired array size?: ";                                  
while ( !(cin >> *limit) || *limit < 0 ) {
    cout << "  Invalid entry. Please enter a positive integer: ";
    cin.clear();
    cin.ignore (1000, 10);
}

int *newarr;                                                                            
newarr = new int[*limit]
    //I'm stuck here
}

7 回答

  • 1

    先验,您应该检查逗号是否存在,如果不存在则声明错误 . 出于这个原因,我将分别处理第一个数字:

    std::vector<int> dest;
    int value;
    std::cin >> value;
    if ( std::cin ) {
        dest.push_back( value );
        char separator;
        while ( std::cin >> separator >> value && separator == ',' ) {
            dest.push_back( value );
        }
    }
    if ( !std::cin.eof() ) {
        std::cerr << "format error in input" << std::endl;
    }
    

    请注意,您不必先询问尺寸 . 如果内存可用,阵列( std::vector )将根据需要自动扩展 .

    最后:在现实生活中的例子中,您可能希望逐行读取,以便在格式错误的情况下输出行号,并从这样的错误中恢复并继续 . 这有点复杂,特别是如果您希望能够在换行符之前或之后接受分隔符 .

  • 1

    所有现有答案都非常出色,但所有答案都针对您的特定任务 . 因此,我编写了一般代码,允许以标准方式输入逗号分隔值:

    template<class T, char sep=','>
    struct comma_sep { //type used for temporary input
        T t; //where data is temporarily read to
        operator const T&() const {return t;} //acts like an int in most cases
    };
    template<class T, char sep>
    std::istream& operator>>(std::istream& in, comma_sep<T,sep>& t) 
    {
        if (!(in >> t.t)) //if we failed to read the int
            return in; //return failure state
        if (in.peek()==sep) //if next character is a comma
            in.ignore(); //extract it from the stream and we're done
        else //if the next character is anything else
            in.clear(); //clear the EOF state, read was successful
        return in; //return 
    }
    

    样品用法http://coliru.stacked-crooked.com/a/a345232cd5381bd2

    typedef std::istream_iterator<comma_sep<int>> istrit; //iterators from the stream
    std::vector<int> vec{istrit(in), istrit()}; //construct the vector from two iterators
    

    由于你是初学者,现在这段代码可能对你来说太过分了,但我想我会发布这个代码是为了完整性 .

  • 0

    您可以使用 getline() 方法,如下所示:

    #include <vector>
    #include <string>
    #include <sstream>
    
    int main() 
    {
      std::string input_str;
      std::vector<int> vect;
    
      std::getline( std::cin, input_str );
    
      std::stringstream ss(str);
    
      int i;
    
      while (ss >> i)
      {
        vect.push_back(i);
    
        if (ss.peek() == ',')
        ss.ignore();
      }
    }
    

    代码从this回答中获取并处理 .

  • 3

    维克多的答案有效,但不仅仅是必要的 . 您可以直接调用cin上的ignore()来跳过输入流中的逗号 .

    此代码的作用是以整数形式读取输入数组的大小,在该元素数量的整数向量中保留空间,然后循环到指定的元素数,交替从标准输入读取整数并跳过分隔逗号(对cin.ignore()的调用) . 一旦它读取了所请求的元素数量,它就会将它们打印出来并退出 .

    #include <iostream>
    #include <iterator>
    #include <limits>
    #include <vector>
    
    using namespace std;
    
    int main() {
        vector<int> vals;
        int i;
        cin >> i;
        vals.reserve(i);
        for (size_t j = 0; j != vals.capacity(); ++j) {
            cin >> i;
            vals.push_back(i);
            cin.ignore(numeric_limits<streamsize>::max(), ',');
        }
        copy(begin(vals), end(vals), ostream_iterator<int>(cout, ", "));
        cout << endl;
    }
    
  • 1
    #include <iostream>
    using namespace std;
    
    int main() {
        int x,i=0;
        char y;               //to store commas
        int arr[50];
        while(!cin.eof()){
            cin>>x>>y;
            arr[i]=x;
            i++;
        }
    
        for(int j=0;j<i;j++)
            cout<<arr[j];     //array contains only the integer part
        return 0;
    }
    
  • 3

    使用C 11中的新std :: stoi函数可以简化代码 . 它在转换时处理输入中的空格,并且仅当特定标记以非数字字符开始时才抛出异常 . 因此,此代码将接受输入

    “12de,32,34 45,45,23xp,”

    容易但拒绝

    “de12,32,34 45,45,23xp,”

    一个问题仍然存在,因为你可以看到,在第一种情况下,它将显示“12,32,34,45,23”,它在截断“34 45”到34的末尾 . 可以添加一个特殊情况来处理这是错误或忽略令牌中间的空格 .

    wchar_t in;
    std::wstring seq;
    std::vector<int> input;
    std::wcout << L"Enter values : ";
    
    while (std::wcin >> std::noskipws >> in)
    {
        if (L'\n' == in || (L',' == in))
        {
            if (!seq.empty()){
                try{
                    input.push_back(std::stoi(seq));
                }catch (std::exception e){ 
                    std::wcout << L"Bad input" << std::endl;
                }
                seq.clear();
            }
            if (L'\n' == in) break;
            else continue;
        }
        seq.push_back(in);
    }
    
    std::wcout << L"Values entered : ";
    std::copy(begin(input), end(input), std::ostream_iterator<int, wchar_t>(std::wcout, L", "));
    std::cout << std::endl;
    
  • 0
    #include<bits/stdc++.h>
    using namespace std;
    int a[1000];
    int main(){
        string s;
        cin>>s;
        int i=0;
        istringstream d(s);
        string b;
        while(getline(d,b,',')){
            a[i]= stoi(b);
            i++;
        }
        for(int j=0;j<i;j++){
            cout<<a[j]<<" ";
        }
    }
    

    这段代码很适合C 11以后,它很简单,我使用了stringstreams和getline和stoi函数

相关问题