In cpp how to use getline() get full sentence without interactive input? - c++

Like the following codes, how to get the whole sentences by getline() function if there is no interactive input?
right now, the input&output is:
input "today is a good day"
output "today"
#include <iostream>
#include <pthread.h>
using namespace std;
string value;
int main(int argc, char *argv[]){
value=argv[1];
cout << value;
return 0;
}

try this
string s;
for(int i = 1; i < argc; i++) {
s += argv[i];
s += " ";
}

Usually you'd handle this in the calling environment, by piping your input.
$ myProgram
<console waiting for input>
vs
$ echo "my input here!" | myProgram
or
$ cat /var/someFile | myProgram
or even
$ netcat 192.168.0.15:80 | myProgram
No code changes required.
Command line arguments are intended for switches and options that alter the program's behaviour.

Related

Reading arguments from a text file using <

I have a txt file called test.txt that looks like this,
hi this is a test
and I have a c++ file called selection_sort.cpp that looks like this,
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
cout << argc << endl;
for (int i = 0; i < argc; i++) {
cout << argv[i] << endl;
}
return 0;
}
right now when I compile my program in my terminal with
g++ selection_sort.cpp -o selection_sort
and then try and print out all of of the arguments I am trying to pass using my code like this
./selection_sort < test.txt
but it only outputs
./selecton_sort
I would like it to output
./selection_sort
hi
this
is
a
test
What am I missing or doing wrong? I need to use the <.
What am I missing or doing wrong? I need to use the <.
This is a shell operator that sends the content of the file to the standard input of the application.
./app < text.file
Will read the file text.file and send the conent to the standard input of the application app. In C++ you can read the standard input via std::cin.
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
std::string word;
while (std::cin >> word) {
std::cout << word << "\n";
}
}
< in bash is used to redirect input. In other words, it redirects the standard input for your process to the file. However, command line arguments (e.g. argv arguments) are not read through standard input, so you cannot capture them from a file by redirecting input.
Rather, they are provided as arguments when running the command in bash to begin with. You can accomplish your goal like so:
./selection_sort $(cat test.txt)
cat is for concatenating files, but if you supply it just one file, it will just output the contents of the file through standard out. The $(x) operation will execute the x command in a subshell, capture its standard output (which in this case is the contents of the file), and then do variable substitution to replace $(x) with said contents.
Edit:
Or, you can just change the way the arguments are accepted, so that they are accepted via standard input. It depends on how you want to be able to run the program.

c++ getline does not seem to recognize newlines in input piped to stdin

This code:
$ cat junk.cpp
#include <stdio.h>
#include <malloc.h>
#include <iostream>
#include <string>
using namespace std;
int
main(int argc, char **argv)
{
string line;
while(getline(cin, line))
{
cout << line << endl;
}
return 0;
}
works fine if I run it, then type "hi" and "there
$ junk
hi
hi
there
there
So far so good.
But I have another program:
$ cat junk1.c
#include <stdio.h>
int
main(int argc, char **argv)
{
int i = 4;
while(i--)
{
printf("abc\n");
sleep(1);
}
return 0;
}
This one outputs 4 lines of "abc\n" and sleeps after each line.
So if I do this:
junk1 | junk
I would expect to see each line of "abc" followed by a 1 second sleep, but instead I see 4 seconds of sleep followed by all 4 "abc" lines at the end.
Apparently getline() is buffering all output from junk1, and only proceding when junk1 terminates.
This is not the behavior I need, because I want to pipe the stdout from a program that runs forever and produces voluminous output, to a program like junk.cpp.
Any idea what is going on here?
Thanks!
This is probably caused by stdout in junk1.c being buffered: all writes to it (by printf or any other means) are collected in an in-memory buffer, and only written to stdout when the program exits.
To force stdout to actually write what it has in the buffer, you have to use flush (in your case, you should use it after every printf).

Will running a shell script from a c++ program automatically display the output of the shell script to the console?

I'm taking a Linux class and I've never done c++ before. My shell script basically does everything on its own, but I'm required to use it from a c++ program. My shell script when run from command line outputs the results I want to back to the console. When I run it from the c++ program, my program compiles and runs but I get no output. Is this because I have some error in my c++ program, or is this supposed to happen because of the way the c++ and shell script interact?
I have seen some questions about grabbing the output from the shell script and using it in the c++ program, but I don't want to do that. Literally all my c++ program does is run the shell script.
I just want the output of my shell script to show on the console. Can you help? I can post the code I'm using if needed.
C++:
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main (int argc, char *argv[]) {
string arg;
arg = string(argv[1]);
if (argc >= 2) {
for (int i=2; i < argc; i++) {
string temp = string(argv[i]);
arg=arg+" "+temp;
}
}
string command;
command = "./findName.sh "+ arg;
//cout << command;
system("command");
return 0;
}
If you want to display the output real-time, you can use something like this:
FILE* outputStream;
char buffer[1024];
outputStream = popen(command,"r");
if (outputStream == NULL)
return 1; //couldn't execute command
while (fgets(buffer, sizeof(buffer), outputStream) != NULL) {
//read output line-by-line to buffer and display it
std::cout << buffer << std::endl;
}
pclose(outputStream);

C++ file-redirection

For faster input, I read that you can do file-redirection and include a file with the cin inputs already set.
In theory it should be used like following:
App.exe inputfile outputfile
As far as I understood from C++ Primer book, The following C++ code[1] should be reading cin input from the text file and shouldn't need to any other special indication like[2]
[2]
include <fstream>
ofstream myfile;
myfile.open ();
[1] The following C++ code...
#include <iostream>
int main()
{
int val;
std::cin >> val; //this value should be read automatically for inputfile
std::cout << val;
return 0;
}
Am I missing something?
To use your code [1] you have to call your program like this:
App.exe < inputfile > outputfile
You can also use:
App.exe < inputfile >> outputfile
In this case the output wouldn't be rewritten with every run of the command, but output will be appended to already existing file.
More information about redirecting input and output in Windows you can find here.
Note that the <, > and >> symbols are to be entered verbatim — they are not just for presentation purposes in this explanation. So, for example:
App.exe < file1 >> file2
In addition to original redirection >/ >> and <
You can redirect std::cin and std::cout too.
Like following:
int main()
{
// Save original std::cin, std::cout
std::streambuf *coutbuf = std::cout.rdbuf();
std::streambuf *cinbuf = std::cin.rdbuf();
std::ofstream out("outfile.txt");
std::ifstream in("infile.txt");
//Read from infile.txt using std::cin
std::cin.rdbuf(in.rdbuf());
//Write to outfile.txt through std::cout
std::cout.rdbuf(out.rdbuf());
std::string test;
std::cin >> test; //from infile.txt
std::cout << test << " "; //to outfile.txt
//Restore back.
std::cin.rdbuf(cinbuf);
std::cout.rdbuf(coutbuf);
}
[I am just explaining the command line argument used in Question]
You can provide file name as command line input to the executible, but then you need to open them in your code.
Like
You have supplied two command line arguments namely inputfile & outputfile
[ App.exe inputfile outputfile ]
Now in your code
#include<iostream>
#include<fstream>
#include<string>
int main(int argc, char * argv[])
{
//argv[0] := A.exe
//argv[1] := inputFile
//argv[2] := outputFile
std::ifstream vInFile(argv[1],std::ios::in);
// notice I have given first command line argument as file name
std::ofstream vOutFile(argv[2],std::ios::out | std::ios::app);
// notice I have given second command line argument as file name
if (vInFile.is_open())
{
std::string line;
getline (vInFile,line); //Fixing it as per the comment made by MSalters
while ( vInFile.good() )
{
vOutFile << line << std::endl;
getline (vInFile,line);
}
vInFile.close();
vOutFile.close();
}
else std::cout << "Unable to open file";
return 0;
}
It is important that you understand the concept of redirection. Redirection reroutes standard input, standard output, and standard error.
The common redirection commands are:
> redirects standard output of a command to a file, overwriting previous content.
$ command > file
>> redirects standard output of a command to a file, appending new content to old content.
$ command >> file
< redirects standard input to a command.
$ command < file
| redirects standard output of a command to another command.
$ command | another_command
2> redirects standard error to a file.
$ command 2> file
$ command > out_file 2> error_file
2>&1 redirects stderr to the same file that stdout was redirected to.
$ command > file 2>&1
You can combine redirection:
# redirect input, output and error redirection
$ command < in_file > out_file 2> error_file
# redirect input and output
$ command < in_file > out_file
# redirect input and error
$ command < in_file 2> error_file
# redirect output and error
$ command > out_file 2> error_file
Even though, it is not part of your question, you can also use other commands are powerful when combined with redirection commands:
sort: sorts lines of text alphabetically.
uniq: filters duplicate, adjacent lines of text.
grep: searches for a text pattern and outputs it.
sed : searches for a text pattern, modifies it, and outputs it.

Running a program from command prompt and using argv in C++

I have written a program that takes the filename from argv[1] and do operations on it .
When debugging from visual studio I pass the filename from project options>>debugging>>command arguments and It works fine and prints all results correctly .
But when trying from the command prompt , I go to the dir of project/debug the I type
program
It works fine and prints "No valid input file" in the same window (Which is my error handling technique)
but when i type
program test.txt
It just does nothing . I think no problem in code because it works fine from the debugger .
Code :
int main(int argc, char *argv[])
{
int nLines;
string str;
if(argv[1]==NULL)
{
std::cout << "Not valid input file" << endl;
return 0 ;
}
ifstream infile(argv[1]);
getline(infile,str);
nLines = atoi(str.c_str());//get number of lines
for(int line=0 ;line < nLines;line++)
{
//int currTime , and a lot of variables ..
//do a lot of stuff and while loops
cout << currTime <<endl ;
}
return 0 ;
}
You don't check if file was successfully opened, whether getline returned error code or not, or if string to integer conversion didn't fail. If any of those error occur, which I guess is the case, nLines will be equal to 0, no cycles will be performed and program will exit with return code 0.
This code worked correctly for me running on the command line.
#include <string>
#include <algorithm>
#include <functional>
#include <vector>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int nLines;
string str;
if(argv[1]==NULL)
{
std::cout << "Not valid input file" << endl;
return 0 ;
}
else
std::cout << "Input file = " << argv[1] << endl;
}
Output :
C:\Users\john.dibling\Documents\Visual Studio 2008\Projects\hacks_vc9\x64\Debug>hacks_vc9.exe hello
Input file = hello
By the way, this code is dangerous, at best:
if(argv[1]==NULL)
You should probably be checking the value of argc before attempting to dereference a possibly-wild pointer.
The file probably contains an invalid numeric first line (perhaps starting with a space or the BOM).
That would explain no output, since if nLines == 0 no output should be expected