1

I have a table of integer, for example :

1,10,100
0,1,2
3,4,5

and i have to read an exact line from the file and ,after,save it in a dynamic array.This is how i tried to read the line but i don't know how to save in a dynamic array.

fstream& Go2Line(fstream& file, unsigned int num){
file.seekg(ios::beg);
for(unsigned int i=0; i < num - 1; ++i)
    file.ignore(numeric_limits<streamsize>::max(),'\n');
return file;}



int main(){ 
fstream file("testo.csv",ios_base::in);
if (!file)
    cout << "Unable to open file file.csv\n";
else
{
    int Number2Go = 1;
    Go2Line(file, Number2Go);

    if (!file)
        cout << "Unable to reach line " << Number2Go << ".\n";
    else
    {
        string line;
        getline(file,line);
        std::stringstream convertor(line);// I Don't know how continue from here

    }
}

return 0;}
Federico
  • 35
  • 1
  • 8
  • Possible duplicates: [stackoverflow c++ read csv](https://www.google.com/search?q=stackoverflow+c%2B%2B+read+csv&ie=utf-8&oe=utf-8) – Thomas Matthews Nov 26 '15 at 23:00

2 Answers2

1

Go2Line can be simplified to make it easier to read and debug

fstream& Go2Line(fstream& file, unsigned int num)
{ 
    file.seekg(ios::beg);
    while (num > 0) // keep going until no more lines
    {
        file.ignore(numeric_limits<streamsize>::max(),'\n');
        --num; // saw a line. reduce number of lines remaining to see
    }
    return file;
}

I recommend using a lot of space for your early programs. It doesn't cost much and makes it really easy to see that braces line up. Take shortcuts later when you have a better grip on the language. But for now use all of the braces, even the optional ones, put them on their own line so they are easy to see, and line them up so you can see at a glance which braces match.

The next bit takes advantage of the ability of getline to use delimiters that are different from just end of line.

std::stringstream convertor(line);
std::string token; // somewhere to put the comma separated value
int numtokens = 0;
while (std::getline(convertor, token, ',') 
{
    numtokens++;
}

Now we know how big of an array we need, we can build the array and store the numbers in it. After we convert them into numbers with std::atoi or similar.

int * array = new int[numtokens];
int index = 0;
while (std::getline(convertor, token, ',') 
{
    //convert token into number with std::atoi or similar
    array[index] = std::atoi(token);
}

And later when you are done, you need to give array's memory back.

delete[] array;

This leads to problems if you forget or an unexpected event occurs and stops you from reaching where you delete[] array;.

For example, what if the input line looks like 10,20,SUCKER!,30? std::atoi is not going to like trying to turn "SUCKER!" into an int and will throw an exception. This may make you miss deleteing array.

A faster way to do it says screw the dynamic array. This is C++!

std::stringstream convertor(line);
std::string token; 
std::vector<int> array; // more on this later
while (std::getline(convertor, token, ',') 
{
    array.push_back(std::atoi(token));
}

All of your numbers are now inside a std::vector. It sizes itself to fit, so you don't have to worry about counting the number of numbers on the line before storing them. It also handles all of its own memory, so when std::atoi throws an exception over "SUCKER!", vector cleans up the mess.

There are also a bunch of improvements I've left out in order to keep the example simple, so happy coding!

user4581301
  • 29,019
  • 5
  • 26
  • 45
  • In this way i have an array of 1 10 100 and an "infinite"number of 0,i think that we have to add a control about the end of the line, but i don't know how – Federico Nov 27 '15 at 13:30
  • @Federico one of the really cool things about an iostream is a built-in boolean operator. `if(stream)` will enter the block if `stream` is in a good state. Almost all stream functions return the stream, so `while(getline(stream, line))` will loop and get lines until the stream cannot be read. That handles your end of file case. Note that the stream has to be (and always should be to ensure you actually read data) tested after a read. [If you test before the read...](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) – user4581301 Nov 27 '15 at 18:23
-2

You can try something like this:

std::list<int> mylist;
char* data = strtok(line, ",");

while(data)
{
    mylist.push_back(atoi(data));
    char* data = strtok(NULL, ",");
}
  • Going to have a wee bit of trouble getting [`strtok`](http://en.cppreference.com/w/cpp/string/byte/strtok) to take a `std::string` as an argument. Don't waste your time with [`line.c_str()`](http://en.cppreference.com/w/cpp/string/basic_string/c_str). It returns a `const char *` – user4581301 Nov 27 '15 at 00:42
  • char* dup = strdup(str.c_str()); token = strtok(dup, " "); free(dup); – Gilles Richer Nov 27 '15 at 00:47