Command Line Test Program -> Only producing first part - c++

The assignment given in class was to test arguments that where provided.The code that wrote(added to this topic) works ( in the sense that it runs) , but it only produces the first word or set of words.
Code:
#include <fstream>
#include <iostream>
using namespace std;
int main ( int argc , char *argv[] )
{
if(argc > 1 )
{
cout << argv[1] << endl;
}
else
{
return -1;
}
ifstream infile(argv[1]);
if (infile.is_open())
{
string words;
while (infile >> words)
{
cout << words <<endl;
}
}
else
{
return -1;
}
infile.close();
}
The given line is :
"This is true" "This is fact"
The outcome it(code) produces is:
This is true
The outcome that I want is:
This is true , this is fact
Another Example:
The given line :
check if this thing works
Output using this code :
check
Wanted output:
check, if, this, thing, works
My question is if I am not adding something in my code that will produce the whole line. Also, I know that my code does not add "," to the output, but I want to worry about one issue at a time.
Some more information:
The file is read and if there is no arg then it does not produce anything, it also works if there is only one arg. he code stops working at more then one arg and quotes.

This line cout << argv[1] << endl; will print your first command line argument (after argument zero which is the application name) to the screen. Command line arguments wrapped in double quotes are treated as a single argument so for your first example argv[1] = This is true and for the second argv[1] = check. That's why you see what you see.
If you understand this you should be able to figure out how to make it print the whole thing. i.e. command line arguments > 1.

Related

C++ getline and append

I'm trying to write a very simple program that reads its standard input line by line (until "end" appears at the beginning of a line). At the same time, it tries to construct a new string that contains the concatenation of all the lines.
The behavior is quite puzzling. The lines are correctly read (as shown by the cout << current << endl line). However, the constructed string isn't what I expect. Instead, it contains only the last read. However, if I replace construct.append(current) by construct.append("foo"), it works perfectly fine.
What am I doing wrong here?
#include <iostream>
#include <string>
#include <cassert>
using namespace std;
int main() {
string construct;
while(true) {
string current;
getline(cin, current);
assert(!cin.eof());
if (current.find("end") == 0) { break; }
cout << current << endl;
construct.append(current);
}
cout << construct << endl;
return 0;
}
Compiled with:
g++ -o main main.cpp -Wall -std=c++0x
Input: input.txt
abcdef
ghij
end
Output: ./main < input.txt
abcdef
ghij
ghijef
If I type the input instead of using a file, it works as expected. Also I get the same result with gcc (linux) and clang (mac os).
I found the problem. My input file was an ascii file with CRLF line terminators (and I'm using a mac). The construct variable was created correctly, but it wasn't displayed properly by the terminal.
I copied the contents of my .txt file over to Word and deleted all of the hard returns, which worked, but that is not always ideal or possible. The character encoding did not seem to have an impact. What solved it is when I appended a line break as well as the string.
Text::Text(string file) {
ifstream in;
string line;
in.open( file.c_str() ); // because the file name is a parameter decided at runtime in my code
while(getline(in,line,'\n')){
fileContents.append(line+"\n"); // fixed by adding "\n" here
}
cout << "\n Final product:\n";
cout << fileContents;
}

Extract Information from colon seperated .txt file, C++

guys. I'm writing this small test program to read the text file from "EXAMPLE.txt" into my main program. At the output, I put "*" to displayed the data during the output is the data that I want to extract it out and locate into an array. Let say, in this test program the data that I wanted to extract is "JY9757AC", "AZ9107AC","GY9Z970C". But after that, I have did a try run and I faced this problem when comes to the output.
EXAMPLE.txt
ABC:JY9757AC
HDMI:AZ9107AC
SNOC:GY9Z970C
MAIN.CPP
main()
{
string output;
ifstream readExample;
readExample.open("EXAMPLE.txt");
while(readExample.eof())
{
getline(readExample,output,':');
cout << "* " << output <<endl;
}
}
OUTPUT
* ABC //while loop output the "ABC", which is the data that I don't want.
* JY9757AC
HDMI //it work's well, as what I expected and so and the SNOC below
* AZ9107AC
SNOC
* GY9Z970C
I have no any idea why is the "* ABC" is shown on the output, is there anything wrong with my logic. or I missed out something inside the while loop? Thank You in advance for helping to solve my code!
The delim parameter for getline replaces the default delimiter for new line which is "\n".
What you are currently getting as a "line" is:
ABC
JY9757AC\nHDMI
AZ9107AC\nSNOC
GY9Z970C
What you can do is more something like this (if your output like GY9Z970C) is fixed-size:
ssize_t len = getline(readExample,output,':');
cout << "* " << (char*)(output + (len - 8)) <<endl;
Output stores the first extraction from Example.txt and prints it followed by *. In the first iteration output = "ABC"; in the second iteration output = "JY9757AC";. I have added a getline() in the while loop that reads the unwanted part of the line. I also added a string[] to store the extracted values in.
#include <fstream>
#include <string>
using namespace std;
int main()
{
string output, notWanted, stringArray[3];
int i = 0;
ifstream readExample;
readExample.open("EXAMPLE.txt");
while (!readExample.eof())
{
getline(readExample, notWanted, ':');
getline(readExample, output);
cout << "* " << output << endl;
stringArray[i++] = output;
}
cin.get();
return 0;
}
First, I assume the while loop is while(!readExample.eof()), otherwise there should be no output at all.
Second, to your question, the first getline(readExample,output,':'); read "ABC" into the output, so at the next line it outputs * ABC, which is exactly what you got. No surprise.

Linux | Segmentation Fault in C++ - Due to the function ifstream

I think I should begin by saying that I've just installed linux(debian) in my pc and have zero foreknowledge about doing things in linux. This problem is probably due to some really simple thing.
The relevant part of the code is similar to this:
ifstream stockNames("names.txt");
while (!stockNames.eof())
{
string snline;
getline(stockNames,snline);
cout << snline << endl;
.
.
.
}
this should print the first line of the file 'names.txt'. Instead it prints an empty line. And when I try to use snline as an input in another function I get the error 'Segmentation Fault'. How should I modify my code to do this? Is there any difference in usage of the ifstream in linux? Cause in windows the code works just fine
I've written the simple code below
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, const char *argv[])
{
string dos = "names.txt";
ifstream stockNames(dos.c_str() );
string snline;
while (getline(stockNames,snline))
{
cout << snline << " ";
}
return 0;
}
content of names.txt is
ABC
DEFG
HBO
instead of showing those line, cout << snline produces nothing
One more update: I've written two more codes.
(1)
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int main(int argc, const char *argv[])
{
cout << "program has initiated" << endl;
ifstream stockNames("names.txt");
if( !stockNames )
cout << "unable to open" << endl;
string snline;
while (getline(stockNames,snline))
{
cout << snline << endl;
}
return 0;
}
Result is as I desired. First 'program has initiated', then ABC, DEFG, HBO in different lines. But when I change this part
cout << snline << endl;
as
cout << snline << " hey" << endl;
Then ABC DEFG HBO does not appear and instead the only output is " hey".
This is crazy, how can this be??
btw I tried to make a debug with ddd and when I check the variable snline, ddd prints the following line
(gdb) print snline
$2 = {static npos = 4294967295, _M_dataplus = {> = {<__gnu_cxx::new_allocator> = {}, }, _M_p = 0x804c1a4 "ABC\r"}}
new mini update: when I change the relevant line as "cout << snline << " " << endl;" what's printed out is ' BC' ' FGH' ' BO' in seperate lines. Why does << operator overwrites over snline??
First of all, your while loop is wrong, because the eof flag (or any other failure flag) is set after an attempt to read from the stream fails; that means, if the attempt to read fails using getline(), the loop doesn't immediately exit, instead the loop continues which is a serious bug with your code.
So write your loop as (an idiomatic way):
string snline;
while (getline(stockNames,snline))
{
cout << snline;
//..
}
std::getline returns istream&, which can be implicitly converted into boolean type. So if getline reads successfully, then the returned value converts to true and the loop will continue, or else it will convert to false and the loop will exit.
After the edit in your question, all I can say that you need to check the stream object before using it to read contents from the file. More specifically, you need to check if the stream has been initialized properly and it has indeed opened the input file (i.e names.txt), and is ready to read data from it.
So try doing this:
//...
ifstream stockNames(dos.c_str() );
if (!stockNames)
{
cout << "file couldn't open properly" << endl;
return 0;
}
string snline;
while (getline(stockNames,snline))
{
cout << snline << " ";
}
Now run this, and see what it prints.
You have a dos file which uses \r\n at the end of each line. Linux doesn't recognise \r as part of the line ending so it gets included in the snline string. \r causes the next thing printed to appear at the beginning of the line so " hey" overwrites the stock names you were expecting to see.
Try
cout << snline << " " << endl;
and you'll see what I mean
stockNames will not actually appear to reach "end of file" until it has tried to input something and received the EOF character. Therefore, you're going to want to re-write your loop as follows:
ifstream stockNames("names.txt");
string snline;
getline(stockNames,snline);
while (!stockNames.eof())
{
cout << snline << endl;
.
.
.
getline(stockNames,snline);
}
or much simply
ifstream stockNames("names.txt");
string snline;
while (getline(stockNames, snline))
{
cout << snline << endl;
.
.
.
}
To answer your question; no, there is no significant difference in how ifstream operates on Linux and Windows. Of course if you write bugged code (as the other two answers have pointed out) then you might run into problems, but I can't see how the eof bug would cause the problems you are describing.
I would concentrate on the part where you say that using snline causes a segmentation fault, that indicates a more serious issue. Could you post code that demonstrates that?
You aren't checking whether the stream opened properly.
std::ifstream stockNames("names.txt");
if (! stockNames) {
std::cerr << "Unable to open file 'names.tex'\n";
}
else {
// Do the rest of your stuff here.
}
Always check status. Don't just plow ahead and assume everything is OK.
BTW, using namespace std; is something you see in a lot of bad books that are trying to save a tiny amount of ink. Try to get out of this bad habit.

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

String is not printing without new line character in C++

I'm opening a file, and getting lines from it.
The first line should say how many variables there are, and what their names are.
The second line should be a logic equation using these variables.
The assignment is to have it print out a truth table for the variables and equation.
The first line the program is taking in is not printing without me inserting a new line character. I tried converting to a string and using both printf and cout.
Main file that inputs everything:
#include "truthTable2.h"
int main(int argc, const char* argv[]){
ifstream inFile;
if(argc != 2){
cout << "Enter an input file name: ";
char *inFileName = "";
cin >> inFileName;
inFile.open(inFileName);
}
else
inFile.open(argv[1]);
TruthTable tTable;
while(!inFile.eof()){
char variableLine[256];
inFile.getline(variableLine, 256);
printf("%s ", variableLine);
string variable(variableLine);
tTable.setVariables(variable);
char formulaLine[256];
inFile.getline(formulaLine, 256);
cout << formulaLine << "\n";
string formula(formulaLine);
tTable.setFormula(formula);
tTable.printTable();
}
inFile.close();
return 0;
}
Sample input:
2 x y
( \wedge x ( \not y ) )
Output from this:
( \wedge x ( \not y ) )
I think whatever is causing this is giving me problems throughout the rest of the program as well. After I tokenize the variableLine it does not print without a new line character and it does not find the second variable when evaluating the formula.
An std::ostream's output needs to be flushed. It is normally flushed automatically when a line-feed \n is written. If you want to force the stream to flush, you can use the std::flush manipulator like so:
std::cout << "foo" << std::flush;
Edit: Although my post clearly answers the question "Why does my line not show up unless I output a \n character?" You said this does not answer your question, so I will attempt some mind reading to try and answer your real question.
Since I have no idea what you really want know, I'll point out several things here that are wrong with your code and it might help you find your problem or clarify your question.
First, if you are using the file name input from std::cin, when argc<2, you will, a 100% guaranteed, cause a failure in your application. The reason is that the character buffer pointed to by inFileName contains a single byte, reserved for the terminating null character. If someone enters any text whatsoever, you will get a buffer overrun. If someone enters an empty string, your program will open no file and inFile.open(...); will return an error code that you don't check, so your program won't crash, but still won't work.
Second, the other line inputs are needlessly limited to 256 characters and are just as dangerous (i.e. lines longer that 256 characters will cause a bufer overrun). Since you eventually create std::string instances out of the content, you should just plainly use std::getline(). It is shorter to type, more general and safer.
Third, the description of your problem is that no output is generated unless you add a \n character. As I explained, this is perfectly normal. From re-reading your post, I can understand that you don't unhderstand why you should have to add one given that there was already one in the input file. The reason you need to add it is because the getline() functions discard the \n character. It is not inserted into your line's buffer.
I've cleaned up some of your code to show you some clear improvements. From this code you will be able to understand the structure of your program, which should also reflect the structure of your input.
#include "truthTable2.h"
int main(int argc, const char* argv[]){
std::ifstream inFile;
if(argc != 2){
cout << "Enter an input file name: ";
std::string inFileName;
std::getline(std::cin, inFileName);
inFile.open(inFileName.c_str());
}
else {
inFile.open(argv[1]);
}
if ( !inFile.is_open() ) {
// Did not successfully open a file. Print error message and exit!
}
TruthTable tTable;
for (std::string variables; std::getline(inFile,variables); )
{
std::cout << variables << std::endl;
tTable.setVariables(variable);
std::string formula std::getline(formula);
std::cout << formula << std::endl;
tTable.setFormula(formula);
tTable.printTable();
}
return 0;
}
From this, I have a question:how is your input structured? Is your input file only consisted of 2 lines? Are there multiple sets of these line pairs? Is there a single line with variables and a bunch of equations? These three cases will lead me to re-structure the program in one of the following fashions:
2 lines only:
ThruthTable table;
std::string variables, equation;
std::getline(file, variables);
std::getline(file, equation);
// ...
Multiple sets:
while ( !inFile.eof() )
{
ThruthTable table;
std::string variables, equation;
std::getline(file, variables);
std::getline(file, equation);
// ...
}
Multiple equations:
ThruthTable table;
std::string variables;
std::getline(variables);
for ( std::string equation; std::getline(file, equation); )
{
std::getline(file, equation);
// ...
}
If what I am seeing is right, the output from printf is the one that is not showing. In that case, either use
fflush(stdout);
Or better, just go with a std::cout for that line since you're writing it in C++ (using the std::flush technique, of course.)