C++, putting vector data into a .csv file - c++

I'm working on something simple, and i want it to be able to take everything within a vector and put it into a .CSV file, where every row would be a new vector and the columns being each position within the vector.
This is my current code, however whenever I open the CSV file it is completely empty.
Any help would be greatly appreciated!
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main()
{
ofstream myfile;
myfile.open("test.csv");
vector<int> arrayOne = { 10, 20, 30, 40, 50 };
for (int i = 0; i < arrayOne.size(); i++)
{
myfile << arrayOne.at(i) << ",";
}
cin.ignore();
cin.ignore();
return 0;
}

As the marked answer is totally correct in the function it demands from OP, but is derivatives in the code drastically. Which can result in an undebugable code or alter the behavior OP intended. pls consider this code:
#include <iostream>
#include <fstream>
#include <vector>
// removed "using namespace std"
int main()
{
std::ofstream myfile; // added "std::"
myfile.open("test.csv");
std::vector<int> arrayOne { 10, 20, 30, 40, 50 };
for (int i = 0; i < arrayOne.size(); i++) { // added "{"
myfile << arrayOne.at(i) << ",";
} // added "{"
myfile.close(); // <- note this correction!!
std::cin.ignore(); // added this
std::cin.ignore(); // added this
return 0;
}
consider not using using namespace std. This namespace includes hundreds of thousand of functions. you may collide with one of them and this is a pain to debug.
The marked answer removes the parentheses {} at the for-loop. NEVER do that, you may run into undebugable problems, when you add one line to your for-loop. This line is no executed in the loop.
The answer also remove vital code from the OP twice: std::cin.ignore();

Close your file like this:
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
int main()
{
ofstream myfile;
myfile.open("test.csv");
vector<int> arrayOne = { 10, 20, 30, 40, 50 };
for (int i = 0; i < arrayOne.size(); i++)
myfile << arrayOne.at(i) << ",";
myfile.close();
return 0;
}
The point here is, output streams are often buffered. When you close the file, close() function ensures, any pending output sequence is written to the file.

Related

I'm stuck on how to read from a text file

/* In the text file I have a char followed by a blankspace then a string. I'm trying to read the char and string into seperated arrays. Any help is appreciated */
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
int main()
{
char arrivOrDepart;
string licensePlt;
ifstream inFile;
inFile.open("Text.txt");
if (!inFile)
{
cout << "Can't open file" << endl;
return 1;
}
for (int i = 0; i < 4; i++)
{
getline(cin, arrivOrDepart[i]);
getline(cin, licensePlt[i]);
}
inFile.close();
cin.get();
return 0;
}
//text file
A QWE123
A ASD123
A ZXC123
A WER123
A SDF123
#include <fstream>
#include <iterator>
#include <vector>
this reads from file into vector
std::ifstream input("d:\\testinput.txt");
std::vector<std::string> bytes(
(std::istreambuf_iterator<std::string>(input)),
(std::istreambuf_iterator<std::string>()));
input.close();
then, just put the data into whatever container you want. you should almost always prefer vector over array btw
There are a few problems with the code:
getline is the wrong tool of choice for this. if you want to split a stream based on spaces, use >>.
arrivOrDepart and licensePlt are not defined as arrays but are used as arrays.
reading from cin, not from file.
My suggested fixes (excluding using vectors instead of arrays):
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std; // avoid using this
int main()
{
const int MAXARRAY = 4; // avoid using magic numbers
char arrivOrDepart[MAXARRAY]; // made an array, but prefer std::vector
string licensePlt[MAXARRAY]; //made an array
ifstream inFile;
inFile.open("Text.txt");
if (!inFile)
{
cout << "Can't open file" << endl;
return 1;
}
string temp;
int i = 0;
while (i < MAXARRAY && // not overrunning the arrays
inFile >> temp >> licensePlt[i] && // read data from file stream
temp.length() == 1) // read only one character for arrivOrDepart
{
arrivOrDepart = temp[0];
i++;
}
inFile.close();
cin.get();
return 0;
}
Recommended reading:
Why is "using namespace std" considered bad practice?
What is a magic number, and why is it bad?
std::vector documentation (Alternate easier to read but often less accurate documentation)
std::getline documentation. Note the third parameter used to set the parsing delimiter.

How to read a CSV file in C++

Here is my code that I have written to read an excel file in csv format in C++. I want to read the file line by line. When I run the code it gives me an error saying
argument list for class template 'array' is missing
Thanks.
#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <array>
using namespace std;
int main() {
array<string , 29>arr;
string line;
int location;
int start = 0;
//int arrayFile[51][28] = { { 0 } };
string fileName;
ifstream infile(fileName);
infile >> line;
//error check
if (infile.fail()) {
cout << "File not Found !" << endl;
exit(1);
}
//reading the file
for (int i = 0; i < 29; i++) {
location = line.find(","); //find the first comma in line
array[i] = line.substr(start, location - start); // separate the information from line up to the comma
line = line.substr(location + 1); //change line to the rest after removing the the abouve piece of the information
}
array[i] = line;
Since you declared using namespace std and included <array>, array is not a variable, but a template class (C++11 STL). You must define an actual array with it like
array<string, 29> arr;
// std::array<std::string, 29> arr;
Then you'll be able to use arr afterwards

Trying to open file and copy it word by word with vector

I'm trying to open a file and read it word by word. I can't figure out where my issue is as it seems to break down after opening the file.
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <vector>
#include <array>
using namespace std;
int main()
{
string path, test;
ifstream inputFile;
vector<string> words;
cout << "What is the path for the input file? ";
getline(cin, path);
inputFile.open(path, ios::in);
while (!inputFile.eof())
{
cin >> test;
words.push_back(test);
}
for (int i = 0; i < words.size(); i++)
{
cout << words.at(i) << endl;
}
inputFile.close();
return 0;
}
while (!inputFile.eof())
{
cin >> test;
words.push_back(test);
}
There are two problems here:
You opened inputFile but then attempt to read from std::cin
"while (!inputFile.eof())" is always the wrong thing to do.
Well, there's also a third problem here:
Using a debugger would've immediately identified both problems. As an example, I loaded the compiled code in a debugger and stepped through it. The issues were readily apparent.
#Sam has all the things you did wrong.
But an alternative to using a loop is just to use iterators to build the array.
std::ifstream file(path);
std::vector<std::string> words(std::istream_iterator<std::string>(file),
std::istream_iterator<std::string>());
To print it out you can use copy.
std::copy(std::begin(words), std::end(words),
std::ostream_iterator(std::cout, "\n"));
Currently this will break words using white space as the separator between words. This means punctuation etc will be included with words. Look here on how to get the streams to treat punctuation as space: How to tokenzie (words) classifying punctuation as space
Thanks to everyone for the help. Here is the final code (for anyone who ends up Googling this in the future)
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <vector>
#include <array>
using namespace std;
int main()
{
string path, test;
ifstream inputFile;
vector<string> words;
cout << "What is the path for the input file? ";
getline(cin, path);
inputFile.open(path, ios::in);
while (inputFile >> test)
{
words.push_back(test);
}
for (int i = 0; i < words.size(); i++)
{
cout << words.at(i) << endl;
}
inputFile.close();
return 0;
}

Reading in lines from a text file in reverse order c++

I need to find a way of reading in the last 6 lines of data from a file.
For example if I have
1
2
3
4
5
6
7
8
9
10
I need to read be able to get
10, 9, 8, 7, 6, 5, 4.
These need to then be put into variables or strings to be outputted later. Currently I have managed to read in the last line of the file but I have no idea how to then read in the other 5 numbers.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main()
{
std::ifstream in("test.txt");
if (in.is_open())
{
std::vector<std::string> lines_in_reverse;
std::string line, line2;
while (std::getline(in, line))
{
// Store the lines in reverse order.
lines_in_reverse.insert(lines_in_reverse.begin(), line);
}
cout << line << endl;
while (std::getline(in, line2))
{
// Store the lines in reverse order.
lines_in_reverse.insert(lines_in_reverse.begin(), line2);
}
cout << line2 << endl;
}
cin.get();
return 0;
}
Can anyone advise a way to this? I do not know of any functions or methods that can help.
EDIT
This method outputs the last 6 numbers from the file however they are backwards and I need a way to reverse them and get rid of the whitespace it prints out.
I'm unsure on how to use reverse and which arguments are required from this - http://en.cppreference.com/w/cpp/algorithm/reverse
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
char x;
ifstream f("test.txt", ios::ate);
streampos size = f.tellg();
for (int var = 1; var <= size; var++){
f.seekg(-var, ios::end);
f.get(x);
reverse(x);
cout << x;
}
cin.get();
return 0;
}
Alot of the responses show me how to reverse the text file using vectors but not the last 6 numbers which is the only information I need.
Regards
It's not a good idea to store all the lines you read in, because there can be e.g. a billion lines.
You only need to store the last 6.
The following code is designed to produce those lines in reverse order, as the question indicates that is a requirement:
#include <iostream>
#include <string>
#include <deque>
using namespace std;
auto main() -> int
{
string line;
deque<string> last_lines;
while( getline( cin, line ) )
{
if( last_lines.size() == 6 )
{
last_lines.pop_back();
}
last_lines.push_front( line );
}
for( auto const& s : last_lines )
{
cout << s << endl;
}
}
The output here is not exactly the question's example
” 10, 9, 8, 7, 6, 5, 4
because that's 7 lines, contradicting the 6 that's stated in the first sentence.
How to read a file and print it reverse, in only three statements of code (excluding declarations and other boilerplate):
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
void read_and_print_reverse_n(std::istream& is, const int n)
{
std::vector<std::string> v;
// This call reads all whitespace-delimited "words" from the input stream
// and appends them to the vector
std::copy(std::istream_iterator<std::string>(is),
std::istream_iterator<std::string>(),
std::back_inserter(v));
// Output the last `n` lines from the input
for (const auto i = v.rbegin();
i < v.rend() && i < v.rbegin() + n;
++i)
{
std::cout << *i << '\n';
}
}
int main()
{
read_and_print_reverse_n(std::cin, 6);
}
References
std::copy
std::istream_iterator
std::back_inserter
I think the answer here would solve the purpose where you store the lines in a vector and iterate the vector from the end.
As you are looking for some direct method to read the file, you can read the file character by character starting from the end using seekg and tellg.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main()
{
char x;
ifstream f("filename.txt",ios::ate);
streampos size = f.tellg();
for(int var=1;var<=size;var++){
f.seekg(-var,ios::end);
f.get(x);
printf("%c",x);
}
return 0;
}
You can also keep a count of \n to keep a track of the number of lines read from the end.

Reading multiple lines of strings from a file and storing it in string array in C++

I have a class called StringList consisting of a constructor and a de-structor. What I am shooting for is for the ability of my program to retain its strings in the array even after it is not running. The way i want to do this is to have my constructor function read strings from a file and store them into my string array (str[]). My de-structor will save my current strings into my file. I am having trouble reading and storing from the file when memory is created. I want each word to be one element in the array.
For example, in the file that is being read from, the strings are stored as such:
HELLO
MOM
DAD
FOUR
YELLOW
I want each word to be a slot. In other words. str[0] = HELLO, str[1]= MOM, str[2]=DAD and such.
Here is my constructor function:
StringList::StringList()
{
numberOfStrings=0;
str = new string[1000000];
ifstream myfile ("Read.txt");
if (myfile.is_open())
{
for (int i = 0; i < 1000000; i++)
{
getline(myfile,str[i]);
numberOfString++;
}
myfile.close();
}
}
Problem here is the for (int i=0; i<100000;i++) line
What this did is continue to fill each blank space into the element until it reached 100000.
Same if i put i<20, it would read all the contents and add blanks to fill to 20. Is there anyway to fill up to the amount of actual strings in the txt. file?
NumberOfStrings++ is outside of your for loop when you read (i.e. it only gets incremented once). Also please consider using std::vector<std::string> instead of a dynamic array.
Here's a version of your code using std::vector instead of an array:
#include <vector>
#include <fstream>
#include <iostream>
#include <string>
class StringList
{
public:
StringList(): str(1000000), numberOfStrings(0)
{
std::ifstream myfile ("Read.txt");
if (myfile.is_open())
{
for (int i = 0; i < str.size(); i++)
{
getline(myfile, str[i]);
numberOfStrings++;
}
myfile.close();
}
}
StringList::~StringList()
{
std::ofstream os("Read.txt");
for (int i = 0; i <numberOfStrings; i++)
{
os << str[i] << std::endl;
}
}
private:
std::vector<std::string> str;
int numberOfStrings;
};
As you can see the changes are rather minimal.
The numberOfStrings variable is only updated once after the for loop has finished. You can also simplify this without the need to specify a large number of lines to read by checking the return value of getline for failure. If you try to read past the end of file is getline will return false.
numberOfStrings = 0;
str = new std::string[1000000];
std::ifstream myfile("Read.txt");
if (myfile.is_open())
{
std::string line;
while(getline(myfile, str[numberOfStrings]))
numberOfStrings++;
myfile.close();
}
You can simplify this even further by using std::vector. To expand on the example provided in your answer StringList might look something like below.
StringList.h
#include <vector>
#include <string>
class StringList
{
public:
StringList();
void PrintWords();
private:
size_t numberOfLines;
std::vector<std::string> str;
};
StringList.cpp to read in single line into each string
#include "StringList.h"
#include <fstream>
StringList::StringList()
{
std::ifstream myfile("Read.txt");
if (myfile.is_open())
{
std::string line;
while(getline(myfile, line))
{
lines_.push_back(line);
}
myfile.close();
}
numberOfLines = str.size();
}
StringList.cpp to read in single word into each string using std::istream_itertor and std::copy
#include "StringList.h"
#include <fstream>
#include <istream>
#include <algorithm> // std::copy
#include <iterator> // istream_iterator
StringList::StringList()
{
std::ifstream myfile("Read.txt");
if (myfile.is_open())
{
std::copy(
istream_iterator<string>(myfile),
istream_iterator<string>(),
back_inserter(str));
}
numberOfLines = str.size();
}
Some other function to print the words
StringList::PrintWords()
{
for(size_t i = 0; i < numberOfLines; ++i)
{
std::cout << str[i] << std::endl;
}
}
I also recommend avoiding using using namespace std in your code. It pulls everything from std into the current scope (typically the global namespace) and can cause conflicts with identifiers.
This would be my approach to reading the data (this doesn't quite work the same as the other answers, but as long as your wordlist doesn't contain words with whitespace, it should work fine).
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
int main()
{
std::fstream myFile("read.txt");
if (myFile.is_open())
{
std::istream_iterator<std::string> iter(myFile), end;
std::vector<std::string> str(iter, end);
// print contents
for (int i = 0; i < str.size(); i++)
std::cout << i << ": " << str[i] << std::endl;
}
}
References:
istream_iterator
vector
You can continue to averse std::vector all you want, but for a scenario like this, it is the best tool for the job.