简体   繁体   中英

Read a specific row of integer from a csv file in c++

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;}

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 delete ing 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!

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, ",");
}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM