reading inputs from file up to specific character cpp - c++

Im tryin to read input.txt include string (move_back; turn_around[radius];).
I should allocate string command and attribute like;
up to ";" is command // move_back; is a command
between "[" and "]" is attribute // [radius] is and attribute
ı write these two program for this but ı need to combine in one program. And also ı dont know how can ı read between "[" "]" ı think ı shoul start reading at "[", finish reading at sight "]" char. ı dont know how to write this code and combine all these.
input.txt
move_back;
turn_around[radius];
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
// reading input from file line by line
void read() {
ifstream file;
file.open("input.txt");
string line;
while (getline(file, line)) {
cout << line << endl;
}
file.close();
}
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
int main()
{
// to find commands reading up to ";"
string s = "move_back; turn_around [radius];move_back [time];";
string delimiter = ";";
vector<string> commands;
int pos = -1;
while (s.find(delimiter) != -1) {
pos = s.find(delimiter);
commands.push_back(s.substr(0, pos));
s = s.substr(pos + delimiter.length());
}
for (int i = 0; i < commands.size(); i++) {
if (isspace(commands[i].at(0)))
commands[i] = commands[i].substr(1);
}
}

Related

Extracting XY coordinates from Gcode using c++ regex parser

I am trying to parse through a gcode file and need to extract the XY coordinates from the uploaded gcode.
I tried to parse but after running my code only the X-coordinate is printing not XY coordinates.
Also, how can I add a stop in the parser when it encounters a G92 in the line.
I want it to parse when line has G1 and stop when it encounters a G92.
#include <iostream>
#include <fstream>
#include <string>
#include <regex>
using namespace std;
int main()
{
ifstream gcode ("circuit.gcode");
string line;
regex coord_regex("[XY].?\\d+.\\d+");
smatch coord_match;
while (getline(gcode, line))
{
if (regex_search(line, coord_match, coord_regex))
{
cout << coord_match[0]<< " - "<< coord_match[1]<< endl;
}
}
return 0;
}
Image
Gcode input
Current Output
So, I figured it out instead of searching for Y in the line I took X as a start and parsed the whole string altogether.
This is the final code
#include <iostream>
#include <fstream>
#include <string>
#include <regex>
using namespace std;
int main()
{
ifstream gcode (test1.gcode");
string line;
regex coord_regex("[X].?\\d+.\\d+.\\s.\\w+.\\d+\\d+");
smatch coord_match;
while (getline(gcode, line))
{
if (regex_search(line, coord_match, coord_regex))
{
if (line.find("G1") != std::string::npos)
{
cout << coord_match[0]<< endl;
}
else if (line.find("G92") != std::string::npos){
break;
}
}
}
return 0;
}

Extract all directory names from a text file

I have a text file in which files names, along with their subdirectory names, could appear at any random places. E.g.
input_file.txt
This is a text file. This line has a file name and location Folder1/file1.dat appearing here.
This is another line: Folder2/file2.txt
Here is yet another line with ../Folder3/Folder4/file3.doc filename and location.
This will be on a Linux system; hence the forward-slashes.
I need a C++ code that can extract all the directory names/locations from this type of file. In the above example, the strings to be extracted would be:
Folder1
Folder2
../Folder3/Folder4
Given the above format of the input file, I suppose the algorithm ought to be something like this:
Go through each line in the file and see if the line has a forward-slash (/) anywhere in it.
If a forward-slash is found in a line, extract the substring between the last occurance of the forward-slash (/) in that line and the last space character that appeared before it.
I have tried several different ways, such as below, but just cannot get it to work, I am afraid.
#include <iostream>
#include <string>
int main(int argc, char* argv[])
{
using std::cout; using std::endl;
unsigned first, last;
if(argc < 2)
{
cout << "\nPlease give valid file name!"<<endl;
exit(1);
}
std::string para_file_name = argv[1]; //The name of the input file.
std::ifstream configfile(para_file_name);
while (getline(configfile, line)) {
if (line.find(" ")) {
if (line.find(" ")!=std::string::npos) first = line.find(" ");
if (line.find("/")!=std::string::npos) last = line.find("/");
std::string DirName = line.substr (first,last-first);
cout << " DirName = " << DirName << endl;
}
}
The code has to be compatible with versions older than C++11 and cannot use fancy external libraries such as Boost. Just native C++ please.
Not the most concise, but more performant than <regex> and works with C++98.
#include <cstdlib> // exit
#include <fstream> // fstream
#include <iostream> // cout
#include <sstream> // istringstream
#include <string> // getline
int main(int argc, char **argv)
{
if (argc < 2)
{
std::cout << "\nPlease give valid file name!\n";
exit(1);
}
// Load the file in
std::string line;
std::fstream file(argv[1]);
// For each line of file...
while (std::getline(file, line))
{
std::istringstream iss(line);
std::string word;
char delim = ' ';
// For each word of line...
while (std::getline(iss, word, delim))
{
size_t pos = word.find_last_of('/');
// Word includes '/'
if (pos != std::string::npos)
{
std::string dir_name = word.substr(0, pos);
std::cout << dir_name << "\n";
}
}
}
}
Output
Folder1
Folder2
../Folder3/Folder4
Maybe overkill, but you could use regex.
#include <iostream>
#include <regex>
#include <string>
int main() {
std::cmatch m;
std::regex_match("This is another line: Folder2/file2.txt", m,
std::regex(".*?([^/ ]+/)+.*"));
std::cout << m.str(1) << std::endl;
return 0;
}
Output
Folder2/

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

How to get part of an .csv file in 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)
}

How do I skip reading a line in a file in C++?

The file contains the following data:
#10000000 AAA 22.145 21.676 21.588
10 TTT 22.145 21.676 21.588
1 ACC 22.145 21.676 21.588
I tried to skip lines starting with "#" using the following code:
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
using namespace std;
int main() {
while( getline("myfile.txt", qlline)) {
stringstream sq(qlline);
int tableEntry;
sq >> tableEntry;
if (tableEntry.find("#") != tableEntry.npos) {
continue;
}
int data = tableEntry;
}
}
But for some reason it gives this error:
Mycode.cc:13: error: request for
member 'find' in 'tableEntry', which
is of non-class type 'int'
Is this more like what you want?
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
fstream fin("myfile.txt");
string line;
while(getline(fin, line))
{
//the following line trims white space from the beginning of the string
line.erase(line.begin(), find_if(line.begin(), line.end(), not1(ptr_fun<int, int>(isspace))));
if(line[0] == '#') continue;
int data;
stringstream(line) >> data;
cout << "Data: " << data << endl;
}
return 0;
}
You try to extract an integer from the line, and then try to find a "#" in the integer. This doesn't make sense, and the compiler complains that there is no find method for integers.
You probably should check the "#" directly on the read line at the beginning of the loop.
Besides that you need to declare qlline and actually open the file somewhere and not just pass a string with it's name to getline. Basically like this:
ifstream myfile("myfile.txt");
string qlline;
while (getline(myfile, qlline)) {
if (qlline.find("#") == 0) {
continue;
}
...
}