C++ 在达到空格字符之前,如何读取未知数量的整数?(C+;+;)

C++ 在达到空格字符之前,如何读取未知数量的整数?(C+;+;),c++,C++,我需要从控制台读取由分隔的数字直到到达空格字符。输入应该是这样的:3;1 -2;-1.1 1;1.3.2。在每一组数字之间可以有一个以上的空格,我需要将每一组数字插入到一个向量中。我最初的想法是这样的: char c; std::vector<double> coordinates; while(std::cin >> c){ if(c != ' ' & c != ';'){ double a = c - 48;

我需要从控制台读取由
分隔的数字直到到达空格字符。输入应该是这样的:
3;1  -2;-1.1     1;1.3.2
。在每一组数字之间可以有一个以上的空格,我需要将每一组数字插入到一个向量中。我最初的想法是这样的:

char c;
std::vector<double> coordinates;
while(std::cin >> c){
    if(c != ' ' & c != ';'){
        double a = c - 48;
        coordinates.push_back(a);
    }
}
double a,b,c,d;
std::vector<Point *> points;
int x = scanf("%lf;%lf;%lf;%lf ",&a,&b,&c,&d);
while(x != EOF){
    if(x == 2){
        points.emplace_back(new Point2D(a,b));
    }
    if(x == 3){
        points.emplace_back(new Point3D(a,b,c));
    }
    if(x==4){
        points.emplace_back(new Point4D(a,b,c,d));
    }
    x = scanf("%lf;%lf;%lf;%lf ", &a,&b,&c,&d);
    if(x == 0) break;   //i don't think this is necesary , but without it my debugger wouldn't work
charc;
向量坐标;
while(std::cin>>c){
如果(c!=''&c!=';'){
双a=c-48;
坐标。推回(a);
}
}

问题是,如果我有负数,就无法使用ASCII将字符转换为整数。如果有人能给我另一种方法来做这种类型的阅读,或者能给我一些建议,我将非常感激

以下是执行所需操作的代码
你可以从中得到你想要的想法
不要忘记阅读评论
我还添加了字符“e”来结束输入

#include <iostream>
#include <vector>
#include <string>
int main()
{
    std::string cnum="";
    std::vector<std::vector<long long>> mainVec;
    int pos=0;
    while (true)
    {
        std::vector<long long> cvec;
        while (true) {
             //std::cin wont get spaces
            char c=getchar(); 
            //we reached the space so lets parse it and go to next num
            if (c == ';') {
                int num;
                try
                {
                    //will throw if can't parse so inside of try cache
                    num=std::atoll(cnum.c_str());
                    cvec.push_back(num);
                }
                catch (const std::exception&)
                {
                    std::cout << "can't parse the number";
                }
              //make ready for next num
                cnum.clear();
            }
            else if (c == ' ') {
               
                int num;
                try
                {                   //will throw if can't parse so inside of try cache
                    num=std::atoll(cnum.c_str());
                    cvec.push_back(num);
                }
                catch (const std::exception&) {
                    std::cout << "can't parse the number";
                }
                //go to next vector
                mainVec.push_back(cvec);
                cvec.clear();
                //or use std::move
                break;
            }
            //end this operation
            else if (c == 'e') {
                int num;
                try
                {                   //will throw if can't parse so inside of try cache
                   num= std::atoll(cnum.c_str());
                    cvec.push_back(num);
                }
                catch (const std::exception&) {
                    std::cout << "can't parse the number";
                }
                //add last vector and break the loops
                mainVec.push_back(cvec);
                goto rest;
            }
            else
                cnum += c;
        }
    }
rest:
    std::cout << "the end";

}
#包括
#包括
#包括
int main()
{
std::string cnum=“”;
std::向量mainVec;
int pos=0;
while(true)
{
std::载体cvec;
while(true){
//标准::cin不会得到空格
char c=getchar();
//我们到达了空间,所以让我们解析它并转到下一个num
如果(c==';'){
int-num;
尝试
{
//如果无法在try缓存内解析,则将抛出
num=std::环礁(cnum.c_str());
cvec.推回(num);
}
捕获(const std::exception&)
{
std::cout您需要的是一种在输入中向前看的方法。如果您知道下一个字符是空格、分号、数字还是减号,那么您就可以正确地决定读取什么

这里有一个函数可以为您实现这一点

int peek_char(istream& input)
{
    int ch = input.get();
    if (ch >= 0)
        input.put_back(ch);
    return ch;
}
使用此函数,您可以在不读取下一个字符的情况下知道下一个字符是什么。。如果没有下一个字符(由于文件结尾),它将返回一个负数。

您可以使用:

自动读取集(std::istream&is){ std::向量集; std::矢量电流_矢量; 双数; while(是>>数字) { 当前向量。推回(数字); 开关(is.peek()) { 大小写“;”://忽略分号 是。忽略(1); 打破 案例“”://移动到下一个集合 set.push_back(标准::移动(当前_向量)); 当前_向量。清除(); 打破 默认值://不需要处理点和数字。EOF在while条件下处理 打破 } } set.push_back(std::move(current_vector));//推最后一个集合 返回集; }
好的,所以我尝试了这里发布的所有建议,但我不能真正让它解决我的问题,主要是因为这些建议使用了我没有学过的高级内容。对于getline建议,它几乎可以工作,但我无法使其完美工作。所以,我记得我以前也做过类似的阅读,但我没有ried使用了这个想法,效果非常好。我不认为这是最好的想法,但这是一个有效的技巧,如果有人会有和我一样的问题,我想在这里发布。我忘了提到的细节是,我知道向量的维数可以是2,3或4,(因为在我的问题中,我需要将该向量视为2、3或4维中的一个点),所以我可以使用scanf进行处理,如下所示:

char c;
std::vector<double> coordinates;
while(std::cin >> c){
    if(c != ' ' & c != ';'){
        double a = c - 48;
        coordinates.push_back(a);
    }
}
double a,b,c,d;
std::vector<Point *> points;
int x = scanf("%lf;%lf;%lf;%lf ",&a,&b,&c,&d);
while(x != EOF){
    if(x == 2){
        points.emplace_back(new Point2D(a,b));
    }
    if(x == 3){
        points.emplace_back(new Point3D(a,b,c));
    }
    if(x==4){
        points.emplace_back(new Point4D(a,b,c,d));
    }
    x = scanf("%lf;%lf;%lf;%lf ", &a,&b,&c,&d);
    if(x == 0) break;   //i don't think this is necesary , but without it my debugger wouldn't work
双a、b、c、d;
std::向量点;
int x=scanf(“%lf;%lf;%lf;%lf;”,&a,&b,&c,&d);
while(x!=EOF){
如果(x==2){
点。向后放置(新点2D(a,b));
}
如果(x==3){
点。向后放置(新点3D(a、b、c));
}
如果(x==4){
点。向后放置(新点4D(a、b、c、d));
}
x=scanf(“%lf;%lf;%lf;%lf”、&a、&b、&c、&d);
如果(x==0)break;//我认为这不是必需的,但是如果没有它,我的调试器将无法工作
问题的想法是,我有一个类点,我在另外3个类中扩展了它,Poin2D,Point3D,Point4D。Point2D有2个坐标,Point3D有3个坐标,Point4D有4个坐标,每个对象都有一个以坐标为参数的构造函数


谢谢大家帮助我!:)

所以数字总是在-9到9之间?或者你也想解析多位数的数字?你听说过吗?使用
getline
和空格作为分隔符。每一行都是向量。在每一个结果行上使用getline和
作为分隔符。每一行是一个整数。请使用
stoi
(检查错误)提取一个整数。将其放入向量。将该向量放入较大的向量。@aschepler是的,数字可以是多位数,所以我不能真正使用ASCII来读取数字。@JohnFilleau you's Idea在我的情况下似乎工作得很好,但我可以使用std::getline读取到EOF吗?就像我可以使用while(std::cin)一样?编辑:没关系,如果我使用(std::getline)它在调试器中不工作,它似乎工作得很好,因为我有一些问题