user2748161
user2748161

Reputation: 89

Loop iteration issue c++

#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

Upvotes: 0

Views: 115

Answers (5)

Zac Howland
Zac Howland

Reputation: 15870

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

Upvotes: 1

Sorin
Sorin

Reputation: 11968

You only read the first line.

Add a loop with a condition like

while (getline(infile, line)) {
    ...
}

Upvotes: 0

Zan Lynx
Zan Lynx

Reputation: 54363

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.

Upvotes: 3

Vlad from Moscow
Vlad from Moscow

Reputation: 311108

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


 }

Upvotes: 1

user2961791
user2961791

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

Upvotes: -1

Related Questions