Hello!!

I thought I would try and post a problem I have been unable to solve as of yet, though I imagine is easy for experts ;oP

I am trying to play around with the mouse functions of Windows, attempting to create a sort of mouse free environment that uses x,y inputs from an eye tracker, (well not yet, at the moments it is a long list of x,y coordinates in a .csv file)

I am used to programming a bit in java, however c++ seemed more appropriate for this task, so I am persevering. Anyway, I am having trouble in being able to separate the values in the csv file, there are only 2 columns, x and y respectively, and what I am after is to firstly

a) read in the file
b) read the first line
c) Distinguish the two values separated by a comma (x and y)
d) assign to two integer variables posx and posy
e) go to the next line and repeat c) to d)

From here, I will be using the x,y coordinates to pass to the mouse movement functions I found using the API. I know this is a simple task (probably) as I am fairly confident I could write the file parsing in Java fairly easy, however with C++ being new to me I am strugging a bit,

Any help would be appreciated in extracting the information from the csv file and passing to the variables,

Kind Regards,
David

PS, for your info, I have been messing with c++ and the csv file and managed to get it to extract all the info and display it, not amazing I know, but it may be a bit of a base for those who can help

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{  
  string line;
  ifstream eyetrack ("eyetrack1test.csv");
  if (eyetrack.is_open())
  {
    while (! eyetrack.eof() )
    {
      getline (eyetrack,line);
      cout << line << endl;
    }
    eyetrack.close();
  }

  else cout << "Unable to open file"; 

  return 0;
}

First, don't use the return value of eof() to control loops. Intsted call the stream directly within the conditional. In this case it would be:

while (getline (eyetrack, line))
  cout << line << endl;

Then you can query eof() to determine if input stopped due to finding end of file marker or for some other reason.

if(eyetrack.eof())
  cout << "file read complete;
else
  cerr << "failure to read complete file";

Second, when parsing information you need to know when to stop. Maybe you'll stop after reading in a certain amount of information or maybe you'll stop when you find given flag or maybe you'll stop for some other reason. In C++ the most common tool for getting input involve input streams and the methods assoicated with them.

In particular, the >> operator will skip leading whitespace characters and stop input upon finding the first whitespace char after it's found a non-whitespace char. It leaves the terminating whitespace char in the input stream however, since it will just ignore it the next time >> is called. In your case the newline char at the end of each line is a whitespace char, so you might be able to use >> somehow in the code.

On the other hand, getline() is a very useful method as it can be used to terminate after a given number of char have been read in or as a result of finding a declared terminating char----which defaults to the newline char. getline() will remove whatever terminating char it finds, if it finds any. In your case you could use the comma as the terminating char in one call to getline() and the newline in a second call to getline().

You could use getline() to get the precomma data and >> to get the post comma data. however, the newline left in the input stream after the call to >> will still be there on the alternating call to getline() and will therefore be entered into the string used by getline(), which isn't something you. So, if you must use both getline() and >> in the same program, be sure the input stream is in the appropriate state each time you are going to call the different methods. That usually means clearing the stream with the ignore() method after the last in a string of >> and before the call to getline(). Usually, it's just as easy to use getline() exclusively and not mix the input methods in the first place, but to each their own.

Many thanks for your reply, I should of probably of explained further..

The integers held in the .csv file are as follows...

194.11,162.64
195.36,163.22
195.76,165.06
196.57,163.43
195.41,161.59
195.79,162.43
195.62,164.22

And the reason why I used eof in the else statement was just because i want all the values until the end of the file, there are no white spaces so I dont have to code to expect them...

What is the best method of extracting these? into sets of x,y coordinates that i can give to variables xpos, ypos. I have looked and researched parsing methods but they seem overly complicated for my task, and can't seem to find anything in texts which is helping me either!!

Kind regards,
David

This is actually easier than you think in C++

#include <iostream>
#include <sstream>
...
while (getline( eyetrack, line )) {
  if (line.empty()) continue;
  stringstream ss( line );
  { string val;
    getline( ss, val, ',' );
    stringstream( val ) >> x;
    }
  { string val;
    getline( ss, val );
    stringstream( val ) >> y;
    }
  }

This snippit is, of course, without any error checking other than skipping blank lines...

>>there are no white spaces

Yes there is. When writing to the file to have the format as posted there's a newline char at the end of each line, with the possible exception of the last line in the file. White space char include the following characters: space, tab, newline, carraige return, etc.

Also, 194.11 is a variable value of a string, double or float, but it most definitely isn't a value that can be stored as an int (integer) type variable.

This article has been dead for over six months. Start a new discussion instead.