How to read data from an open pipe: example needed - c++

could anyone provide a small example or direct me to proper reading material in order to solve the following problem:
ls | ./myprog
What I would like to achieve is that my program reads information from ls and just print it on the screen.
I need c++ example, and if possible to do this through boost lib
thnx
P.S.
Thank you all it worked

In C, all you need to do is read the file descriptor 0:
read(0, …, …);
In C++, you can do this by using std::cin:
#include <iostream>
int main() {
std::cin >> /* a variable you want to direct the input to */
return 0;
}
That's standard C++ that is fully compatible with boost. For the way to use it, I leave it to you to read more on the manual and the plethora of examples you can find online.
for opening a file or reading from stdin you can do something in the following fashion:
shared_ptr<istream> input;
if (filename == "-" || filename == "")
input.reset(&cin, [](...){});
else
input.reset(new ifstream(filename.c_str()));
// ...
(answer copied from https://stackoverflow.com/a/2159469/1290438)
Basically, if you don't give a filename parameter, you consider data comes from stdin. That's the way cat works.

this code matches exactly your Problem:
#include <iostream>
using namespace std;
int main()
{
while (true)
{
string x;
cin >> x;
cout << x << endl;
}
}
you have to put this code into your "myprog" cpp file and then type the command you've mentioned.
It simply puts the input from the ls program to your screen

Related

How to read multiple files on C++

My problem is :
First read a file named symbols.txt. This file consist of many
lines, each line consist of 2 elements : an uppercase letter and a
string, this file is ended by a hash(#).
Second read a file named dict.txt. This file consist of many
words(string) . Ended by a hash(#)
Third read a file named handin.txt. This file consist of some
numbers which you're gonna working on it. Ended by a hash(#)
Print your output in a file named handout.txt
This is my code but I'm not sure that I let in read the input right. Please check it for me. Thanks a lot.
#include<bits/stdc++.h>
using namespace std;
int main() {
freopen("symbols.txt" , "r" , stdin);
// input the letter and the string
char X ; string Y ;
while(cin >> X >> Y && X != '#' ) {
// my code goes here
}
freopen("dict.txt" , "r" , stdin) ;
// input the strings here
freopen("handin.txt", "r" , stdin);
// input the numbers here
/ *
Here is my code
* /
freopen("handout.txt" , "w" , stdout);
// let in print the output here
}
#include<bits/stdc++.h>
Don't do this. Here's why
using namespace std;
Don't do this either. Here's why
freopen("symbols.txt" , "r" , stdin);
This is very bad! You're using std::freopen to associate a file with stdin. Then later on, you're using std::cin to read from the file. What you're doing is very "hacky" and this might work sometimes but not always. stdin (from C) and std::cin (from C++) are not required to be linked like this. freopen is a C API so you shouldn't use it in C++ anyway.
What you should do is open an input file stream (std::ifstream) and read from that. That might look a little bit like this:
#include <string> // std::string
#include <fstream> // std::ifstream std::ofstream
#include <iostream> // std::cerr
int main() {
std::ifstream symbols("symbols.txt");
if (!symbols.is_open()) {
// There was a problem opening the symbols file
// Maybe it was missing
// You should end the program here and write an error message
std::cerr << "Failed to open \"symbols.txt\"\n";
// returning an error code of 0 means "everything is fine"
// returning anything else means "something went wrong"
return 1;
}
// Try to choose more descriptive names than "X" and "Y"
char X;
std::string Y;
while (symbols >> X >> Y && X != '#') {
// ...
}
// ...
}
You code will be clearer if you create a new std::ifstream for each file you open (rather than reusing the same one). Error checking is important. You should make sure to check that the file actually opened before using it. To write your output to "handout.txt", you would use an output file stream (std::ofstream) instead.
There's something that might trip you up. Take this "symbols.txt" file:
A many words
B on the same line
C could cause problems
#
If we try to read it using the current code, we run into trouble:
symbols >> X >> Y;
// X is 'A'
// Y is "many" rather than "many words" as you might expect
If there's only one word on each line then this shouldn't be an issue, but if there are multiple words, then you might need to use std::getline. std::getline does what it says on the tin. It reads the whole line and writes it to the given string.
You'd use it like this:
while (symbols >> X && X != '#' && std::getline(symbols, Y)) {
// ...
}
Please make sure you understand the code (read some of the links) before you copy it off of StackOverflow.

Why My Language translator program in Visual C++ overwriting a file with nothing instead of the translation

I have developed a program for translating words in english to my native language.Everything works fine with no errors, except that I am not getting the desired output.
The program asks a user for an input file in which there are english words, then it will read the file and write the translations in my native language to an output file specified by the user. My problem is that the program writes nothing to the output file. I even chose a non-empty output file but all I have seen and understood is that the program overwrits all what are in the output file with nothing.
Please I am asking for someone's help in this difficult time because I have exhausted all my thinking.
Below is the complete program:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h >
#include <conio.h>
#include <iomanip>
#include <cctype>
#include <ctype.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
string Identifier;
ofstream outfile;
ifstream infile;
static string fname1, fname2;
char a = (char)infile.get();
void Display(){
outfile << "Nuna";
}
void gettok(){
Identifier = "";
if (isalnum(a)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
Identifier = a;
while (isalnum(a = (char)infile.get()))
Identifier += a;
while (isspace(a = (char)infile.get())){
if (Identifier == "Display"){
Display();
a = (char)infile.get();
}
}
}
}
int main(){
cout << "Enter name of the file to be translated ";
cin >> fname1;
cout << "Enter new file name";
cin >> fname2;
infile.open(fname1);
if (infile.fail())
{
cerr << " No such a file Exist";
exit(1);
}
outfile.open(fname2);
if (outfile.fail())
{
cerr << "Unable to create a file";
exit(1);
}
while (!infile.eof())
{
gettok();
}
infile.close();
outfile.close();
}
Thank you sir, #TimStraubinger for your guide.
1. Firstly, based on my definition of the Display() function, I just want the program to be in such a way that whenever the english word
Display is read in the input file, then the Display() function is called whose job is to write the translation of the word display as "Nuna" to the output file. I want to have a function for translating each english word as I have done for the word Display. But if there is a better way, help me out.
2. I used "char a = (char)infile.get() " because i want to declare "a" as global variable to be known and used by all of my functions and furthermore, I can't open a file outside the "main" function. So, I searched and thought of ways but all failed!
Please any one's help is welcomed!
There are many things wrong with this, here are my main suggestions. Firstly, your code is hard to read and confusing and defies lots of good convention. I recommend you follow a few textbook examples with C++ and learn to organize your code better so that we can better help you. As for your code, some more obvious problems are as follows:
char a = (char)infile.get()
Here, you're trying to access the file before it is opened. This needs to be called after infile is opened.
And to see something written to the file, you have the condition:
if (Identifier == "Display"){
Display();
a = (char)infile.get();
}
Why does the accumulator string, Identifier, need to have "Display" stored in order to write something to the file? (I highly recommend you find a better function name for Display(), which suggests you're writing something to the screen.) Also, inside the while (isspace(a = (char)infile.get())) loop, infile.get() will be called twice every loop, once to check the loop condition and once because you wrote it in additionally. This will cause every other character to be skipped in that loop.

ofstream does not create file when running with CLion using CMake

I have this code to create a file, when I run it with CLion it prints out to the console but does not create file, how can I fix this? thanks
#include <iostream>
#include <fstream>
using namespace std;
int main() {
ofstream log_file;
log_file.open("sample23.txt");
if (log_file.is_open())
std::cout << "Open";
log_file << "stuff" << endl;
log_file.close();
return 0;
}
The file may be created into another directory (the working directory).
You can find that location (and change it if needed) as indicated here:
How do I change the working directory for my program
make sure to flush before closing because file is empty
try this out
ofstream f;
f.open( "sample.txt", ios::out );
f << flush;
f.close();
3 things here:
1.) In order to output to another file, you must make another variable like this:
ifstream someoutputfile;
someoutputfile.open("filename");
2.) you actually must make another variable to be "placeholder" of sorts that will automatically assign the first thing your file finds and assigns that to. This may depend on what datatype (int, double, string etc) your input file consists of. Instead of:
log_file << "stuff" << endl;
you can do something like this...
// if my input file is integers for instance..
int data = 0;
log_file >> data;
This can also work for if your file contains multiple data types.
ex:
// if I have two different data types...
string somebody;
int data = 0;
log_file >> data >> somebody;
3.) to output your file data to the screen, just follow a similar way as the example in #1.
someoutputfile << data << somebody << endl;
in addition, dont forget to close the data of BOTH your input and output files:
someoutputfile.close()
Hope that helps in some way :)

Create an array with external file in C++

I have 4 days of training in C++, so bear with me.
Two data files are required to evaluate a multiple-choice examination. The first file
(booklet.dat) contains the correct answers. The total number of questions is 50. A sample
file is given below:
ACBAADDBCBDDAACDBACCABDCABCCBDDABCACABABABCBDBAABD
The second file (answer.dat) contains the students’ answers. Each line has one student
record that contains the following information:
The student’s answers (a total of 50 answers) in the same format as above (* indicates no answer)., followed by Student ID and Student Name. Example:
AACCBDBC*DBCBDAAABDBCBDBAA*BCBDD*BABDBCDAABDCBDBDA 6555 MAHMUT
CBBDBC*BDBDBDBABABABBBBBABBABBBBD*BBBCBBDBABBBDC** 6448 SINAN
ACB*ADDBCBDDAACDBACCABDCABCCBDDABCACABABABCBDBAABD 6559 CAGIL
I have a homework assignment to write a C++ program that counts the total number of correct answers by each student and outputs this information to another file called report.dat. In this file, the student’s IDs, names and scores must be given. Each correct answer is worth 1 point. For the sample files given above, the output should be as follows:
6555 MAHMUT 10
6448 SINAN 12
6550 CAGIL 49
Here's what I have so far:
include <iostream>
include <fstream>
using namespace std;
int main()
{
char booklet[50] answers[50]
int counter
// Link answers with booklet.dat
booklet = ifstream
input_file("booklet.dat");
return 0;
// Link answers with answers.dat
answers = ifstream
input_file("answer.dat");
return 0;
while (booklet==answers)
{
counter++
cout << "The student had">>counter>> "answers right";
}
}
I'm not even sure I am in the correct direction. I know I need to create an array from the file booklet.dat and another one from the file answer.dat. Then the comparison has to be made and the matches between the two have to be counted.
I don't expect anyone to do the assignment for me, i just need a nudge in the right direction.
1.) On your Syntax:
a) Each line in C++ has to end with an ";". There are some lines in your excample which don't. (Normally your compile should point at this or the following line with an error)
b) Multiple variable definitions need a "," in between two different variables.
2.) I would recommend you to use something like that:
(have a look at C++ Reference fstream)
EDIT: just a little outline, which is not complete in this form, just to give you and idea ;-)
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
int nr_of_students = 1000; /* Or any number you'd like to analyze */
int stud_nr[nr_of_students];
string stud_name[nr_of_students];
int stud_count[nr_of_students];
fstream in_out;
in_out.open("filename.dat",fstream::in); // fstream::in for reading from file
// fstream::out for writing to this file
if(in_out.is_open())
{
for(lines=0;(in_out>>answers && lines<nr_of_students);lines++)
{
in_out >> stud_nr[lines]; /* EDIT: sorry hat some index confusions here... */
in_out >> stud_name[lines];
stud_count[lines]=0;
for(int i=0;i<50;i++)
{
/* comparison between the booklet_array and the answers_array */
/* Count up the stud_count[lines] for each right comparison */
}
}
/* some simmilar code for the output-file */
}
else cout << "Error reading " << "filename.dat" << endl;
return 1;
}
3.) Your code would also get more performance with vectors.
A good Tutorial would be: Tutorial part I
and you find part 2 in the comments there
4.) you can achieve a more dynamic code with argc and argv**, just google for that
I hope these comments help you a little bit to carry on ;)
You are already on the right direction. Basically you want to load the answer key into an array for fast comparison and then you need to check the answers of each student and each time they get a correct answer you increment a counter and write the ID, name and score for each student. There are problems with your code such as missing semicolons.
Also please note that returning exits a function and that no statements after an unconditional return are executed, returning from main terminates your program.
The normal approach to open a file for reading is:
#include<fstream>
#include<string>
int main()
{
std::ifstream input_file("inputfilename");
// since the answer key is one line
// and each students answer , id and name are also one line
// getting that line using std::getline() would be sufficient
std::string line;
std::getline(input_file, line);
// line would now contain the entire first line except the newline character
std::getline(input_file, line);
//now line would now contain the second line in the file
return 0;
}
Writing to a file is similar we use ofstream to open a file for writing.
Like so:
#include<fstream>
int main()
{
std::ofstream output_file("outputfilename");
// lets say we have a string and an int that we want to write
std::string line_to_write("Hello File");
int number = 42;
output_file << line_to_write << number; // writes the string and then 42 on the same line
output_file << '\n'; // writes the newline character so that next writes would appear on another line
return 0;
}
For references to the standard library and C++ in general when you need to know the available functions to do something I recommend cppreference here are the specific pages on ifstream and ofstream.

C++ Read/write file on Unix

I know this is a very specific question. I am compiling a c++ code using g++ compiler on a unix machine.
I have the following one line code to read a text file specified as parameter in C++: test.cc
int main(int argc, char *argv[])
{
ifstream inputfile(argv[1]);
}
Now after compiling with g++, I will call it as:
./test file.txt
But what should I do, if I want to call it as
./test <file.txt
In short how do I do a file read using default input/output
You should check the arguments to main to see if there is an argument given to the program. If it is then you can use that as the file, otherwise you use std::cin.
Here is an example:
void do_something(istream &input)
{
// Read some stuff from the input
}
int main(int argc, char *argv[])
{
if (argc == 1)
do_something(cin);
else if (argc == 2)
do_something(ifstream(argv[1]));
else
{
cout << "Error: Must supply a file\n";
return 1;
}
}
The reason I call another function to read and process the input, is because you can not assign streams, but must use references or pointers. It's also good to put separate tasks in separate functions, because it will increase readability of the code.
When you want to read from standard input, use std::cin instead of opening your own stream.
For example:
std::string s;
std::getline(std::cin, s);
Using < redirects that file to stdin, so you'd get at it via std::cin in c++.
You need instead to read from stdin, da file.
in other words read from the keyboard.
when you pipe stuff in, it will be read as if typed from the keyboard.
You can do what most of the Unix commands do: read from the file if the filename is specified. If the file name is missing read from standard input.
The cin object is already defined in iostream. Just read from cin instead of inputfile.
Perhaps
ifstream &myin;
if (argc>1) {
ifstream* inputfilep = new infstream(argv[1]);
myin = *inputfile;
}
else myin = cin;
/* do your input on myin */
you will need to modify your example to check argc to see if any command line arguments are passed in, as the input redirection is stripped off by the shell so if argc is 0 then read from standard in as given by the other examples, otherwise as your example code.
You don't have to do anything.
Just write your program as if your are reading from the command line.