C++ : read a csv file and extract some parts - c++

A .csv file is written like this:
M9005U00-X30A0S00-1;BAS;X;-0.002;-0.095
S707RY00-X30AOS00-1;HMV;X;+0.002;+0.081
W3005U00-X30BOJ00-1;BAS;X;+0.026;-0.138
H307QZ00-X30BOJ00-1;HMV;X;-0.025;+0.122
....
now I want to create a function, i.e.
double find_and_extract (string sss)
when this function is used with a keyword as its parameter, for example
find_and_extract (W3005U00-X30BOJ00-1);
it will search in the .csv file line by line, find corresponding line (in this case it should be the third line), and extract the certin part "+0.026" in this line, return as a double.
How should I write this function?
edit: Here is the code i've written so far:
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <vector>
#include <iterator>
#include <cstdlib>
#include <cstdio>
#include <sstream>
#include <stdlib.h>
using namespace std;
void main()
{
find_and_extract (W3005U00-X30BOJ00-1);
}
double find_and_extract (string sss)
{
vector<string> vecarray;
ifstream infile("C:\\Data\\testdata.csv");
string temppo;
string contnt;
char csv_extract[40];
stringstream ss;
vector <string>::iterator ptr;
while (!infile.eof())
{
infile.getline(csv_extract,40);
ss << csv_extract;
ss >> contnt;
vecarray.push_back(contnt);
}
for (ptr=vecarray.begin();ptr!=vecarray.end();ptr++)
{
if ((*ptr).find(sss)==0)
temppo = (*ptr).substr(27,6);
}
return (strtod(temppo.c_str(),NULL,0));
}
Could anyone help me out to point out the errors?

Seeing as you already have the file as a string, I'd use the Knuth–Morris–Pratt algorithm to find the key, find the position of the 3rd and 4th semi-colons on that line and return the string in between them.
That's just an outline - you'll need to add error handling.

Check out strtok(). This is actually a pretty trivial task, and should be a good learning project if you are still new to C++.

You could use sed: This way, you could search for the key very efficiently, without having to implement an algorithm yourself. When you found the key, you can let sed output the parts of the line you need (use regular expressions to describe the pattern and groupings to print only part of it). After that, it's a simple string to float conversion that can be done in a programming language of your choice.
For starters:
sed -n 's/RegexToMatchYourKeyAndValues/MatchedValues/p'

If the text lines in the file are the same length, you may want to read the lines as blocks (i.e. many lines == 1 block) into a buffer, then search the buffer.
Your performance bottleneck will the reading the data from the file. In general, the search method you choose will be faster than reading in the data.

Related

How to use the delim parameter from getline

I need to make a program in witch I have to read a text from an input file(ifstream fin("input.in")) and store it until the program meets the "#" character. I know it should be doable using fin.getline, but I can't make the "delim" parameter work. I would find useful an explanation of how doe it work, and an example. I already read this, but I couldn't find an example with fin.getline.
This is what I tried, but it doesn't work:
#include <fstream>
#include <string.h>
#include <string>
using namespace std;
ifstream fin("cod.in");
ofstream fout("cod.out");
char chr[100];
for(int i=0;i<n;i++)
{
fin.getline(chr,'#');
fout<<chr<<" ";
}

Reading lines from a file in c++17

I'm a beginner and I'm trying to transform from previous version of c++ to modern c++17.
I'm trying to read lines from a file. The contents are mostly gibberish and I'm doing this as an exercise to learn the language after not using c++ for many years.
The contents of the file I'm reading from are gibberish, i.e:
werweirwer
weriwrwjeie
werjiwrji
(after solving this I'll use it as an exercise to assign lines after filtering as input to constructors, use regex on it and basically develop it until I feel comfortable enough with input/out concepts, which may take some time).
However, it cannot read from the input file, even though it exists and in the same directory as the .cpp file (with reading permissions). IDE is clion if it matters.
Here's the code I used:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
std::vector<std::string> insertToVector(std::string k){
std::vector<std::string> wordvector;
if(k.empty()) {cerr<<"error reading from file: string is empty";}
else {wordvector.push_back(k);}
return wordvector;
}
int main() {
fstream f("k.txt",ios_base::in);
std::string templine;
if(f){
cout<<"Contents: \n";
while(getline(f, templine)){
cout<<"Contents:"<< templine; //just to output it simply
std::vector<std::string> wordvector= insertToVector(templine);
std::for_each(wordvector.begin(),wordvector.end(),[](const std::string word){std::cout<<word;}); //vector output
}
}else{
std::cerr<<"couldn't open file";
}
f.close();
return 0;
}
Additional question I wonder whether it is good to read lines with while(getline()) or to use while(!f.eof()) instead? Which is better in your opinion?
One more thing, I'm quite confused with functors and std::function, could you show me how to implement the insertToVector as std::function or functor and call it correctly?
Thank you very much. Doing my best to learn
EDIT: Fixed it using auto path = fs::path, and then using that reference with fstream. Worked well. Thank you very much for your explanations in the comments. Helped a lot in learning.

C++ print palindromes from a text file

Check if a string is palindrome
I was using the link above to try to solve this problem (among many others, Ive been trying to solve it various ways all day with no dice, this is my first C++). All other examples are usually in an array format, and I can't make assumptions as to the length of a word.
I'm trying to make a program to detect if a word is a palindrome or not. I have a text file with one word per line, and want to test each word, line by line, if it is a palindrome, and if so to print it to the screen, and if not, to ignore it and not print it.
I figured the best way to locate the palindromes was to reverse the word line by line and match it to the original, and if they are the same (==), then to print it. Here is what I have so far:
#include <iostream>
#include <vector>
#include <string>
#include <cctype>
#include <fstream>
using namespace std;
int main(int argc, char *argv[]) {
std::string line;
std::ifstream infile("wordlist.txt");
}
string reverse(string line){
if (line == string(line.rbegin(), line.rend())) {
cout << string;
}
}
All help is appreciated
I guess your question is a homework question and you would like to get some information on how to complete the C++ coding.
You look not to know how to read file contents in C++.
Here's a link of how to do it:
Read file-contents into a string in C++
I am not very sure about what you specifically would like to be answered. If your question is a homework question, here's some info of how to ask:
https://meta.stackexchange.com/questions/10811/how-do-i-ask-and-answer-homework-questions
#include<iostream>
#include<algorithm>
#include<string.h>
#include<fstream>
using namespace std;
int main() {
string line="", line_rev="";
ifstream infile;
infile.open("wordlist.txt");
do{
infile>>line;
line_rev=line;
reverse(line_rev.begin(), line_rev.end());
if(line==line_rev)
cout<<line<<endl;
}while(getline(infile, line));
//if(infile.is_open()){cout<<"open"<<endl;} //to check if file is open or not
//else{cout<<"unable to open"<<endl;}
return 0;
}
This is the solution. i dont know why you are writing "string reverse(string line)" out side the main() function.

Read string math-formula into cpp as double from external input-file

I am relatively new to c++ coding and try to write a program to solve differential equations numerically. I use codeBlocks as the compiler for that and work under windows. The numeric solver already works well.
My program contains of some very long formulas which are created by mathematica and converted into cpp-language. Then the formulas are stored in a .txt-file.I can already read the formula as a string, but not use it to calculate things because the program has to interpret the formula as a double-type math and not as a string. The problem here is, that my formula does not contain only numbers, but letters as variables (their value is set in the program) and other mathematical symbols. That is why I think I cannot just use "atof" (http://www.cplusplus.com/reference/cstdlib/atof/?kw=atof) or other conversion functions. (If I am wrong at this point, I would be glad to learn how to use the function for this problem!)
Here is some example code from my little program:
//Program to solve ODEs
#include <iostream>
#include <math.h>
#include <cmath>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include <time.h> //to measure the time
#include <stdio.h>
#include <conio.h>
using namespace std;
int main(void)
{
double k1=0;
ifstream file("Formelvu1.txt");//file with the fromula
string line;
stringstream longform;
while(getline(file, line)){ //read the formula and store them
longform << line; //store the string in "longform"
cout << longform;
}
return 0;
for(double t=0; t<10; t++){
k1 = (longform) * t; //simple operation with the formula
}
return 0;
}
This code doesn't work, becuase longform is no double...
longform is a string with something like: ab+pow(t,3)-sin(tb)/x.
I already found several questions related to this topic, but none of them was easy enough for me to understand or the right thing I want to do:
How can I convert string to double in C++?
From what I understand is this guy trying the nearest from what I wish to do:
Evaluate math formula from String using ScriptEngine
But I don't understand the code completely.
If it is useful for my problem: What does this part do?
try{
return (Double)engine.eval(tmp);
}
catch(Exception fexp)
{
}
I also heard about parser which can interpret the xpressions line muparser:
http://muparser.beltoforion.de/mup_eval.html
But I don't know if this would be more than I need...
I appreciate every answer/response and help with this problem.
Thank you!
You have to study carefully what is included in the basic C/C++ language and standard library and what not.
However, if you get a C++ compatible expression from mathematica, then you can let the C++ compiler do its work as in
double myfunc(double a, double b, double c, double t, double x) {
return
#include "Formelvu1.txt"
;
}

Read line from file: Unable to use getline()

I have the task to write a function that reads a line from a text file (renamed to .dat, however it contains only text), but I am out of options for a solution because of the following points:
I am using Borland C++ Version 5.02, and no, I CAN´T download another compiler because I dont have admin rights on my laptop and the guy who has the needed password isnt there until next week.
The compiler does not accept using namespace std, and also it doesnt accept getline(), no matter if string and iostream are included or not.
I am trying to find a solution or at least the tiniest approach, but I am unable to find one.
So my question is: How do I read a line from a simple textfile without using getline() (cin.getline works, the ones from string or fstream doesnt) ? The textfile contains several lines like these:
1234;12.05.03;08:44:23; XY12-AB;A1-12;Timeout
2345;12.05.03;09:04:34;XY1-CD;A22-9;Connection refused
And the numbers/letters between the ; need to be stored in variables so they can be worked with.
Im not asking for you to write my code, but I am reallyreaylly frustrated and my instructor is no help.
Live long and prosper,
Me.
http://www.cplusplus.com/reference/string/string/getline/
If you cant use (which you really shouldnt)
using namespace std
Then refer to your namespace with :: operator
For example:
std::string
Now try to write your own code using std:: and comment if you still cant do it.
Also, there is a lot of other options than std::getline() to read line of text.
Ref: Read file line by line
Option 1:
Try using the C's fgets() function.
Option 2:
You mention that cin.getline() works. You can freopen stdin with the input file and then cin will point to mentioned file. After that cin.getline() will read from the file:
Downside: After the freopen you will not be able to accept any input from the user.
Example: Note this has not been tried using g++ but I guess it should work with Borland too.
#include <iostream>
#include <stdio.h>
int main() {
char buf[1000];
freopen("somefile.dat", "r", stdin);
while (cin.getline(buf, sizeof(buf)).good()) {
// Now buf contains a line
// Do something with it
}
return 0;
}
Try using
getline(cin >> ws, variableName);
But first, you have to use
using namespace std;
I'm having the same problem while i using multi dimensional array on structs into a file, i have try different ways. But then i tried this one and it's work for me.
So in my case it gonna be like this
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ifstream myFile;
myFile.open("test.txt");
int count = 0;
while (!myFile.eof())
{
getline(myFile >> ws, data[count].string1);
getline(myFile >> ws, data[count].string2);
myFile >> data[count].int1;
for (int i = 0; i < data[count].int1; i++) {
getline(myFile >> ws, data[count].data2[i].string3);
}
count++;
}
return 0;
}
For more : https://www.geeksforgeeks.org/problem-with-getline-after-cin/