I need to read numbers from console separated by ;
until i get to the space character. The input should look something like this: 3;1 -2;-1;1 1;1;3;2
. There can by more than one space between each set of numbers and i need to insert each set of numbers into a vector . My initial ideea was something like this:
char c;
std::vector<double> coordinates;
while(std::cin >> c){
if(c != ' ' & c != ';'){
double a = c - 48;
coordinates.push_back(a);
}
}
The problem with this is that converting a char to an integer using ASCII can't be made if I have negative numbers. If anyone could give me another method to do this type of reading or can give me some advice I would appreciate it very much!
here's the code to do what you want
you can get the idea you wanted from it
don't forget to read comments
i also added char 'e' to end input
#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";
}
you can do the optimizations yourself (reducing rapeated code in each if case)
What you need is a way to look ahead in the input. If you know whether the next character is a space, a semi-colon, a digit or a minus sign then you can make the correct decision on what to read.
Here's function that does this for you
int peek_char(istream& input)
{
int ch = input.get();
if (ch >= 0)
input.put_back(ch);
return ch;
}
With this function you know what the next character is going to be without reading it . If there is no next character (because of end of file) it will return a negative number.
You could use istream::peek
:
auto read_sets(std::istream& is) {
std::vector<std::vector<double>> sets;
std::vector<double> current_vector;
double number;
while (is >> number)
{
current_vector.push_back(number);
switch (is.peek())
{
case ';': // ignore semicolons
is.ignore(1);
break;
case ' ': // move to the next set
sets.push_back(std::move(current_vector));
current_vector.clear();
break;
default: // no need to handle dots and digits. EOF is handled in while condition
break;
}
}
sets.push_back(std::move(current_vector)); // push the last set
return sets;
}
Ok so i tried all the suggestions that were posted here, and i couldn't really make it work for my problem, mostly because these suggestions used advanced stuff that i haven't learn. For the getline suggestion it was almost working but i couldn't make it work perfectly. So, i remembered that i did a similar kind of reading before and i tried to use that idea and it worked very good. I don't think that it's the best idea but it's a trick that works and i wanted to post it here if anyone will have the same problem as me. The detail that i forgot to mention is that i know the dimension of the vector can be 2, 3 or 4, (because i need to treat that vector as a point in 2,3 or 4 dimension in my problem) so i can use scanf for that, like this:
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
The idea of the problem is that i have a class Point that i extended in 3 more classes, Poin2D, Point3D, Point4D. Point2D has 2 coordinates, Point3D has 3 coordinates and Point4D has 4 coordinates and each object has a constructor with the coordinates as parameters
Thanks everyone for trying to help me! :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.