0
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>

using namespace std;

int main()
{
    string line;
    ifstream infile ("Input.csv");
    vector<string> table;
    string word;
    if(infile.is_open())
    {
        getline(infile,line);
        istringstream iss(line);

        while(!iss.eof())
        {
            getline(iss,word, ',');
            table.push_back(word);
        }
    }

    for(int index=0; index<11; ++index)
    {
        cout<< "Element" << index << ":" << table.at(index) << endl ;
    }
    infile.close();
}

In the above program I am reading values from input file and splitting based on comma and finally storing the values into a vector.

when I print vector I am able to view only the first line of input file.

Input file:

     CountryCode,Country,ItemCode,Item,ElementGroup,ElementCode,Element,Year,Unit,Value,Flag
     100,India,3010,Population - Est. & Proj.,511,511,Total Population - Both sexes,1961,1000,456950,
     100,India,3010,Population - Est. & Proj.,511,511,Total Population - Both sexes,1962,1000,466337,
     100,India,3010,Population - Est. & Proj.,511,511,Total Population - Both sexes,1963,1000,476025,
     100,India,3010,Population - Est. & Proj.,511,511,Total Population - Both sexes,1964,1000,486039,

Output:

  Element0:CountryCode
  Element1:Country
  Element2:ItemCode
  Element3:Item
  Element4:ElementGroup
  Element5:ElementCode
  Element6:Element
  Element7:Year
  Element8:Unit
  Element9:Value
  Element10:Flag

Problem: Only 1st line is being printed

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173
user2748161
  • 89
  • 1
  • 3
  • 15

5 Answers5

3

I suggest rewriting it like this:

int main()
{
    string line;
    ifstream infile ("Input.csv");
    vector<string> table;
    string word;
    while(getline(infile, line))
    {
        istringstream iss(line);

        while(getline(iss,word, ','))
        {
            table.push_back(word);
        }
    }

    for(int index=0; index<11; ++index)
    {
        cout<< "Element" << index << ":" << table.at(index) << endl ;
    }
    infile.close();
}

The stream will return false from getline and most other operations whenever it is invalid. So if it didn't open, the while loop won't run. And when it reaches EOF, the while loop will stop. Much simpler to read this way I think.

Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
1

You read only one line of the file

if(infile.is_open())
 {
  getline(infile,line);
  istringstream iss(line);

   while(!iss.eof())
   {
     getline(iss,word, ',');
     table.push_back(word);
   }


 }

If you need to read all lines of the file then you can write instead

while (getline(infile,line))
 {
  istringstream iss(line);

   while(!iss.eof())
   {
     getline(iss,word, ',');
     table.push_back(word);
   }


 }
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • I added while loop and changed the condition in my for loop for(int index=0; table.size(); ++index) but I am getting error: std::out_of_range what() : vector::_M_range_check – user2748161 Nov 06 '13 at 18:36
  • you don't want to do `while(!iss.eof())` either. Move the getline into the while condition and you have it. – Zac Howland Nov 06 '13 at 18:36
1

You have several issues, addressed below:

int main()
{
    std::string line;
    std::ifstream infile ("Input.csv");
    std::vector<std::string> table;
    while (std::getline(infile, line)) // this is the loop you want to read the file
    {
        std::istringstream iss(line);
        std::string word;
        while (std::getline(iss, word, ',')) // there are better ways to do this, but this will work
        {
            table.push_back(word);
        }
    }    

    for(int index=0; index<table.size(); ++index) // loop through the whole size
    {
        std::cout<< "Element" << index << ":" << table[index] << std::endl ;
    }

    infile.close();
    return 0;
}

Alternatively, you can avoid the use of nested while loops altogether:

struct csv_reader : std::ctype<char>
{
    csv_reader() : std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table()
    {
        static std::vector<std::ctype_base::mask> rc(table_size, std::ctype_base::mask());
        rc['\n'] = std::ctype_base::space;
        rc[','] = std::ctype_base::space;
        return &rc[0];
    }
};

int main()
{
    std::string line;
    std::ifstream infile ("Input.csv");
    csv_reader reader;
    infile.imbue(std::locale(std::locale(), &reader);
    std::vector<std::string> table{std::istream_iterator<std::string>(infile), std::istream_iterator<std::string>()};
    // or 
    //std::vector<std::string> table;
    //std::copy(std::istream_iterator<std::string>(infile), std::istream_iterator<std::string>(), std::back_inserter(table)); 

    for(int index=0; index<table.size(); ++index) // loop through the whole size
    {
        std::cout<< "Element" << index << ":" << table[index] << std::endl ;
    }

    infile.close();
    return 0;
}
Zac Howland
  • 15,777
  • 1
  • 26
  • 42
0

You only read the first line.

Add a loop with a condition like

while (getline(infile, line)) {
    ...
}
Sorin
  • 11,863
  • 22
  • 26
-1

Your for loop only print the first 11 posts from the array. You should it to the lenght of the array.

Not sure what the syntax is for c++ for length of the table but that should be the issue.

  for(int index=0; index<table.size(); ++index)
         {
            cout<< "Element" << index << ":" << table.at(index) << endl ;
         }