How to get part of an .csv file in C++? - c++

I am pretty new to C++.
I just want to get a certain field on a ".csv" file, not all off it.
I am pretty sure, it must be very easy, but I don't know how to do it.
Here is my code to get all the ".csv" content :
#include <iostream>
#include <fstream>
#include <string>
// #include "Patient.h"
using namespace std;
int main()
{
// CPatient patient;
ifstream file("C:/Users/Alex/Desktop/STAGE/test.csv");
if(file)
{
// the file did open well
string line;
while(getline(file, line, ';')) //Until we did not reach the end we read
{
cout << line << endl; //Console Result
}
}
else
{
cout << "ERROR: Could not open this file." << endl;
}
system("PAUSE");
return 0;
}

If you can use boost libraries, then boost::tokenizer would provide the functionality you require. Most notablty, it correctly handles quoted field values that contain commas. The following is a code snippet copied from the linked page:
// simple_example_2.cpp
#include<iostream>
#include<boost/tokenizer.hpp>
#include<string>
int main(){
using namespace std;
using namespace boost;
string s = "Field 1,\"putting quotes around fields, allows commas\",Field 3";
tokenizer<escaped_list_separator<char> > tok(s);
for(tokenizer<escaped_list_separator<char> >::iterator beg=tok.begin();
beg!=tok.end();
++beg)
{
cout << *beg << "\n";
}
}
You could pass each ligne read to a tokenizer and extract the fields you require.

Try reading whole lines and split them afterwards:
int N = 5; // search the fifth field
char separator = ';';
while (std::getline(fichier, ligne)) {
// search for the Nth field
std::string::size_type pos = 0;
for (int i = 1; i < N; ++i)
pos = ligne.find_first_of(separator, pos) + 1;
std::string::size_type end = ligne.find_first_of(separator, pos);
// field is between [pos, end)
}

Related

unique words from a file c++

ts been 3 days i just cant identify whats wrong with the program the program should compare words by words instead it only comparing a character to charcter its is showing like if i have words like (aaa bbb cc dd ) the result its printing is a b and same is the sentence file if i put paragraphs to compare its only comparing few character please help me
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream myfile("unique.text");
int count = 0;
string temp;
string a;
int i,j;
while(getline(myfile,temp))
{
for(i=0 ; i < sizeof(temp); i++)
{
for(int j = 0; j < i; j++)
{
if (temp[i] == temp[j])
break;
}
if (i == j)
cout << temp [i] <<" , ";
}
myfile.close ();
}
You have a couple of problems
temp is of type string. sizeof is not the way to determine the length of a string (it's used for determining things like the number of bytes in an int). You want:
temp.length()
Secondly, indexing into a string (temp[n]) gives you the nth character, not the nth word.
You can make getline split into words by adding a third delimiter parameter:
getline (myfile, temp, ' '))
So, some bugs in your code.
Mixing up characters and strings, closing the file in the while loop and not storing last words.
One recommenadtion. Before you write code, write comments for what you want to do.
Meaning, make a design, before you start coding. That is very important.
For your problem at hand in the title of this thread:
unique words from a file c++
I prepared 3 different solutions. The first is just using very simple constructs. The second is using a std::vector. And, the 3rd is the C++ solution using the C++ algorithm library.
Please see:
Simple, but lengthy
And not recommended, because we should not use raw pointers for owned memory and should not use new
#include <iostream>
#include <fstream>
#include <string>
const std::string fileName{ "unique.text" };
unsigned int numberOfWords() {
// Here we will count the number of words in the file
unsigned int counter = 0;
// Open the file. File must not be already open
std::ifstream sourceFileStream(fileName);
// Check, if we could open the file
if (sourceFileStream) {
// Simply read all words and increment the counter
std::string temp;
while (sourceFileStream >> temp) ++counter;
}
else {
// In case of problem
std::cerr << "\nCould not open file '" << fileName << "'\n";
}
return counter;
}
int main() {
// Get the number of words in the source file
unsigned size = numberOfWords();
// Allocate a dynamic array of strings. Size is the count of the words in the file
// Including doubles. So we will waste a little bit of space
std::string* words = new std::string[size+1];
// Open the source file
std::ifstream sourceFileStream(fileName);
// Check, if it could be opened
if (sourceFileStream) {
// We will read first into a temporary variable
std::string temp;
// Her we will count number of the unique words
unsigned int wordCounter = 0;
// Read all words in the file
while (sourceFileStream >> temp) {
// We will search, if we have read alread the word before. We assume NO for the beginning
bool wordIsAlreadyPresent = false;
// Go through all alread read words, and check, if the just read word is already existing
for (unsigned int i = 0; i < wordCounter; ++i) {
// Check, if just read word is already in the word array
if (temp == words[i]) {
// Yes it is, set flag, and stop the loop.
wordIsAlreadyPresent = true;
break;
}
}
// if the word was not already there
if (! wordIsAlreadyPresent) {
// Then add the just read temporary word into our array
words[wordCounter] = temp;
// And increment the counter
++wordCounter;
}
}
// Show all read unique words
for (unsigned int i = 0; i < wordCounter; ++i) {
std::cout << words[i] << "\n";
}
}
else { // In case of error
std::cerr << "\nCould not open file '" << fileName << "'\n";
}
delete[] words;
}
Using a vector. Already more compact and better readable
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
const std::string fileName{ "unique.text" };
int main() {
// Open the source file
std::ifstream sourceFileStream(fileName);
// Check, if the source file is oepen
if (sourceFileStream) {
// Temporary string for holding just read words
std::string temp;
// In this vector we will store all unique words
std::vector<std::string> words;
// Read all words from the source file
while (sourceFileStream >> temp) {
// We will search, if we have read alread the word before. We assume NO for the beginning
bool wordIsAlreadyPresent = false;
// Go through all alread read words, and check, if the just read word is already existing
for (unsigned int i = 0; i < words.size(); ++i) {
// Check, if just read word is already in the word vector
if (temp == words[i]) {
// Yes it is, set flag, and stop the loop.
wordIsAlreadyPresent = true;
break;
}
}
// if the word was not already there
if (not wordIsAlreadyPresent) {
// Then add the just read temporary word into our array
words.push_back(temp);
}
}
for (unsigned int i = 0; i < words.size(); ++i) {
std::cout << words[i] << "\n";
}
}
else {
std::cerr << "\nCould not open file '" << fileName << "'\n";
}
}
And 3., more advance C++ programming. Just very few lines and elegant code.
But too difficult to understand for starters.
#include <iostream>
#include <fstream>
#include <set>
#include <string>
#include <iterator>
#include <algorithm>
const std::string fileName{ "unique.text" };
int main() {
// Open the source file and check, if it could be opend and there is no failure
if (std::ifstream sourceFileStream(fileName); sourceFileStream) {
// Read all words (everything delimited by a white space) into a set
std::set words(std::istream_iterator<std::string>(sourceFileStream), {});
// Now we have a set with all unique words. Show this on the screen
std::copy(words.begin(), words.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
}
// If we could not open the source file
else {
std::cerr << "\nCould not open file '" << fileName << "'\n";
}
return 0;
}

How to parse table of numbers in C++

I need to parse a table of numbers formatted as ascii text. There are 36 space delimited signed integers per line of text and about 3000 lines in the file. The input file is generated by me in Matlab so I could modify the format. On the other hand, I also want to be able to parse the same file in VHDL and so ascii text is about the only format possible.
So far, I have a little program like this that can loop through all the lines of the input file. I just haven't found a way to get individual numbers out of the line. I am not a C++ purest. I would consider fscanf() but 36 numbers is a bit much for that. Please suggest practical ways to get numbers out of a text file.
int main()
{
string line;
ifstream myfile("CorrOut.dat");
if (!myfile.is_open())
cout << "Unable to open file";
else{
while (getline(myfile, line))
{
cout << line << '\n';
}
myfile.close();
}
return 0;
}
Use std::istringstream. Here is an example:
#include <sstream>
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
string line;
istringstream strm;
int num;
ifstream ifs("YourData");
while (getline(ifs, line))
{
istringstream strm(line);
while ( strm >> num )
cout << num << " ";
cout << "\n";
}
}
Live Example
If you want to create a table, use a std::vector or other suitable container:
#include <sstream>
#include <string>
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
string line;
// our 2 dimensional table
vector<vector<int>> table;
istringstream strm;
int num;
ifstream ifs("YourData");
while (getline(ifs, line))
{
vector<int> vInt;
istringstream strm(line);
while ( strm >> num )
vInt.push_back(num);
table.push_back(vInt);
}
}
The table vector gets populated, row by row. Note we created an intermediate vector to store each row, and then that row gets added to the table.
Live Example
You can use a few different approaches, the one offered above is probable the quickest of them, however in case you have different delimitation characters you may consider one of the following solutions:
The first solution, read strings line by line. After that it use the find function in order to find the first position o the specific delimiter. It then removes the number read and continues till the delimiter is not found anymore.
You can customize the delimiter by modifying the delimiter variable value.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string line;
ifstream myfile("CorrOut.dat");
string delimiter = " ";
size_t pos = 0;
string token;
vector<vector<int>> data;
if (!myfile.is_open())
cout << "Unable to open file";
else {
while (getline(myfile, line))
{
vector<int> temp;
pos = 0;
while ((pos = line.find(delimiter)) != std::string::npos) {
token = line.substr(0, pos);
std::cout << token << std::endl;
line.erase(0, pos + delimiter.length());
temp.push_back(atoi(token.c_str()));
}
data.push_back(temp);
}
myfile.close();
}
return 0;
}
The second solution make use of regex and it doesn't care about the delimiter use, it will search and match any integers found in the string.
#include <iostream>
#include <string>
#include <regex> // The new library introduced in C++ 11
#include <fstream>
using namespace std;
int main()
{
string line;
ifstream myfile("CorrOut.dat");
std::smatch m;
std::regex e("[-+]?\\d+");
vector<vector<int>> data;
if (!myfile.is_open())
cout << "Unable to open file";
else {
while (getline(myfile, line))
{
vector<int> temp;
while (regex_search(line, m, e)) {
for (auto x : m) {
std::cout << x.str() << " ";
temp.push_back(atoi(x.str().c_str()));
}
std::cout << std::endl;
line = m.suffix().str();
}
data.push_back(temp);
}
myfile.close();
}
return 0;
}

"unkown parser error" in c++ netbeans

Sorry in advance, I posted a picture but I don't have the rep yet :( The error at line 1 says "Unknown parser error" repeated over four lines, and starting at the ReadFile class line pretty much each line has an error saying "unexpected token". I have included all of the custom header files from a folder either by right clicking "header" under project and adding the folder containing them or by right clicking the project name itself and adding the folder there. The private folder containing the private snippets of the headers are also included. Anyone have any ideas? This is for a free collection of lectures by Stanford, and you have to download and install their custom headers.. The instructor is using Visual c++, but that shouldn't mean I can't use the files for Netbeans right, their just .h files..?
#include "genlib.h"
#include <iostream>
#include <fstream>
#include "map.h"
#include "random.h"
#include "set.h"
using namespace std;
void ReadFile(ifstream &in, Map<int> &m)
{
while (true) {
string word;
in >> word;
if (in.fail()) break;
if (m.containsKey(word))
m[word]++;
else
m[word] = 1;
}
Map<int>::Iterator itr = m.iterator();
string max;
int maxCount = 0;
while (itr.hasNext()) {
string key = itr.next();
if (m[key] > maxCount) {
max = key;
maxCount = m[key];
}
}
cout << "Max is " << max << " = " << maxCount << endl;
}
void TestRandom()
{
Set<int> seen;
while (true) {
int num = RandomInteger(1, 100);
if (seen.contains(num)) break;
seen.add(num);
}
Set<int>::Iterator itr = seen.iterator();
while (itr.hasNext())
cout << itr.next() << endl;
}
int main()
{
ifstream in("burgh.txt");
Map<int> counts;
ReadFile(in, counts);
Randomize();
TestRandom();
return 0;
}
In your ReadFile function (in multiple places) you are attempting to use a string as the key to a Map with integers as keys.
string word;
in >> word;
if (in.fail()) break;
if (m.containsKey(word))
m[word]++;
In order to do this properly you will need to parse your string input into an integer. This can be achieved through the stoi function or similar.
Example
string word;
in >> word;
int iKey = stoi(word, nullptr);
if (in.fail()) break;
if (m.containsKey(iKey))
m[iKey]++;

Read a file of strings with quotes and commas into string array

Let's say I have a file of names such as:
"erica","bosley","bob","david","janice"
That is, quotes around each name, each name separated by a comma with no space in between.
I want to read these into an array of strings, but can't seem to find the ignore/get/getline/whatever combo to work. I imagine this is a common problem but I'm trying to get better at file I/O and don't know much yet. Here's a basic version that just reads in the entire file as one string (NOT what I want, obviously):
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
fstream iFile("names.txt", ios::in);
string names[5];
int index = 0;
while(iFile)
{
iFile >> names[index];
index++;
}
for(int i = 0; i < 5; i++)
{
cout << "names[" << i << "]: " << names[i] << endl;
}
Output:
names[0]: "erica","bosley","bob","david","janice"
names[1]:
names[2]:
names[3]:
names[4]:
Also, I understand why it all gets read as a single string, but then why are the remaining elements not filled with garbage?
To be clear, I want the output to look like:
names[0]: erica
names[1]: bosley
names[2]: bob
names[3]: david
names[4]: janice
The easiest way to handle this:
Read the entire file and place it into a string, Here is an example of how to do it.
Split the string that you got from number 1. Here is an example of how to do that.
Stream extraction delimits by a space. Therefore the entire file gets read as one string. What you want instead is to split the string by commas.
#include <iostream>
#include <fstream>
#include <algorithm>
#include <sstream>
fstream iFile("names.txt", ios::in);
string file;
iFile >> file;
std::istringstream ss(file);
std::string token;
std::vector<std::string> names;
while(std::getline(ss, token, ',')) {
names.push_back(token);
}
To remove the quotes, use this code:
for (unsigned int i = 0; i < names.size(); i++) {
auto it = std::remove_if(names[i].begin(), names[i].end(), [&] (char c) { return c == '"'; });
names[i] = std::string(names[i].begin(), it);
}
remove_if returns the end iterator for the transformed string, which is why you construct the new string with (s.begin(), it).
Then output it:
for (unsigned int i = 0; i < names.size(); i++) {
std::cout << "names["<<i<<"]: " << names[i] << std::endl;
}
Live Example

Trying to read from a file and skip punctuation in C++, tips?

I'm trying to read from a file, and make a vector of all the words from the file. What I tried to do below is have the user input the filename, and then have the code open the file, and skip characters if they aren't alphanumeric, then input that to a file.
Right now it just closes immediately when I input the filename. Any idea what I could be doing wrong?
#include <vector>
#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
int main()
{
string line; //for storing words
vector<string> words; //unspecified size vector
string whichbook;
cout << "Welcome to the book analysis program. Please input the filename of the book you would like to analyze: ";
cin >> whichbook;
cout << endl;
ifstream bookread;
//could be issue
//ofstream bookoutput("results.txt");
bookread.open(whichbook.c_str());
//assert(!bookread.fail());
if(bookread.is_open()){
while(bookread.good()){
getline(bookread, line);
cout << line;
while(isalnum(bookread)){
words.push_back(bookread);
}
}
}
cout << words[];
}
I think I'd do the job a bit differently. Since you want to ignore all but alphanumeric characters, I'd start by defining a locale that treats all other characters as white space:
struct digits_only: std::ctype<char> {
digits_only(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table() {
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
std::fill(&rc['0'], &rc['9']+1, std::ctype_base::digit);
std::fill(&rc['a'], &rc['z']+1, std::ctype_base::lower);
std::fill(&rc['A'], &rc['Z']+1, std::ctype_base::upper);
return &rc[0];
}
};
That makes reading words/numbers from the stream quite trivial. For example:
int main() {
char const test[] = "This is a bunch=of-words and 2#numbers#4(with)stuff to\tseparate,them, I think.";
std::istringstream infile(test);
infile.imbue(std::locale(std::locale(), new digits_only));
std::copy(std::istream_iterator<std::string>(infile),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}
For the moment, I've copied the words/numbers to standard output, but copying to a vector just means giving a different iterator to std::copy. For real use, we'd undoubtedly want to get the data from an std::ifstream as well, but (again) it's just a matter of supplying the correct iterator. Just open the file, imbue it with the locale, and read your words/numbers. All the punctuation, etc., will be ignored automatically.
The following would read every line, skip non-alpha numeric characters and add each line as an item to the output vector. You can adapt it so it outputs words instead of lines. I did not want to provide the entire solution, as this looks a bit like a homework problem.
#include <vector>
#include <sstream>
#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string line; //for storing words
vector<string> words; //unspecified size vector
string whichbook;
cout << "Welcome to the book analysis program. Please input the filename of the book you would like to analyze: ";
cin >> whichbook;
cout << endl;
ifstream bookread;
//could be issue
//ofstream bookoutput("results.txt");
bookread.open(whichbook.c_str());
//assert(!bookread.fail());
if(bookread.is_open()){
while(!(bookread.eof())){
line = "";
getline(bookread, line);
string lineToAdd = "";
for(int i = 0 ; i < line.size(); ++i)
{
if(isalnum(line[i]) || line[i] == ' ')
{
if(line[i] == ' ')
lineToAdd.append(" ");
else
{ // just add the newly read character to the string 'lineToAdd'
stringstream ss;
string s;
ss << line[i];
ss >> s;
lineToAdd.append(s);
}
}
}
words.push_back(lineToAdd);
}
}
for(int i = 0 ; i < words.size(); ++i)
cout << words[i] + " ";
return 0;
}