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.)
Related
I am learning C++. I want to take multiple line string as input but I can't. I am using getline() for it but it is taking only one line input. When I press enter for writing next line it stoped taking input and print the first line.
I want to give input like the example below
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
But it takes only the first line input.
My code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
getline(cin, s);
cout << s << endl;
return 0;
}
Please help me to know how can I do that.
Thank you.
Either you write a loop to read individual lines and concatenate them to a single string, thats what this answer suggests. If you are fine with designating a specific character to signal the end of the input, you can use the getline overload that takes a delimiter as parameter:
#include <iostream>
#include <string>
int main() {
std::string s;
std::getline(std::cin,s,'x');
std::cout << s;
}
The user would have to type an x to end input, so this input
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
x
would result in this output:
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
Of course this won't work when the string to be entered contains x, which renders the approach rather useless.
However, instead of using a "real" character as delimiter you can use the EOF character (EOF = end of file) like this:
std::getline(std::cin, s, static_cast<char>(EOF));
Then input is terminated by whatever your terminal interprets as EOF, eg Ctrl-d in linux.
Thanks to #darcamo for enlightening me on the EOF part.
You can only read one line at a time with std::getline if you don’t provide your own delimiter. If you want to accumulate multiple lines, one at a time, you need a place to put the result. Define a second string. Read a line at a time into s with std::getline, and then append s to the result string. Like this:
std::string result;
std::string s;
while (std::getline(std::cin, s))
result += s;
You can take several lines using the code below if you know how many lines you will input.
int line=3, t;
string s, bigString;
for(int i=0 ; i<line ; i++)
{
getline(cin,s); // This is to input the sentence
bigString += s + "\n";
}
cout << bigString;
If you don't know how many lines you will input (Input from file until end of file) then you can check this.
string s;
vector<string> all;
while(getline(cin,s))
{
all.push_back(s);// This is to input the sentence
}
for(auto i:all)
{
cout << i << endl;
}
I've been trying to read some information in from a .txt file in C++ but it's not all working like I expect. Here is some example code:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char words[255];
int value = 0;
ifstream input_stream("test.txt");
input_stream >> value;
input_stream.getline(words, 256);
cout << value << endl;
cout << words << endl;
}
And test.txt contains:
1234
WordOne WordTwo
What I expect is for the code to print the two lines contained in the text file, but instead I just get:
1234
I've been reading about getline and istream but can't seem to find any solutions so any help would be appreciated.
Thanks
The newline character remains in the input stream after the read of the integer:
// Always check result to ensure variables correctly assigned a value.
if (input_stream >> value)
{
}
Then, the call to getline() reads the newline character and stops, producing an empty string. To correct, consume the newline character before calling getline() (options include using getline() or ignore()).
Note there is a version std::getline() that accepts a std::string as its argument to avoid using a fixed sized array of char, which is used incorrectly in the posted code.
ifstream's getline method gathers input until one of two options is hit. Either a terminating character or the size passed in is reached. In your case, the newline terminator is encountered before the size is reached.
Use another getline to retrieve the second line of text.
Reference
The problem you are seeing is that the first newline after 1234 is not consumed by input_stream>>(int); so the next getline only reads to the end of that file.
This is a very constructed scenario, commonly found in schoolwork. The more common scenario when reading a textfile is to consider the entire file as linebased text.
In this case the more convenient
string line;
while( std::getline( input_stream, line ) ){
}
is appropriate, and way less error prone.
The textfile would commonly have a predefined format. Perhaps name = value lines, and are parsed as such after the line is read from the file.
Here is a somewhat corrected version of your original code:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char words[256]; // was 255
int value = 0;
ifstream input_stream("test.txt");
input_stream >> value;
input_stream.ignore(); // skip '\n'
input_stream.getline(words, 256);
cout << value << endl;
cout << words << endl;
}
Also, I would advise you to use a string instead of a char[] and use the other getline function.
Somehow when I run this code and it comes to inputting strings, the first string where i=0 is being skipped and it starts entering strings from A[1]. So I end up with A[0] filled with random stuff from memory. Can someone please point at the problem?
cin>>s;
char** A;
A = new char *[s];
cout<<"now please fill the strings"<<endl;
for (int i=0;i<s;i++)
{
A[i] = new char[100];
cout<<"string "<<i<<": ";
gets(A[i]);
}
That code is horrible. Here's how it should look like in real C++:
#include <string>
#include <iostream>
#include <vector>
int main()
{
std::cout << "Please start entering lines. A blank line or "
<< "EOF (Ctrl-D) will terminate the input.\n";
std::vector<std::string> lines;
for (std::string line; std::getline(std::cin, line) && !line.empty(); )
{
lines.push_back(line);
}
std::cout << "Thank you, goodbye.\n";
}
Note the absence of any pointers or new expressions.
If you like you can add a little prompt print by adding std::cout << "> " && at the beginning of the conditional check in the for loop.
Probably because you're using gets()... never use gets()
Use fgets() instead.
gets vs fgets
The problem is that cin>>s; just picks up the number you want and leaves a \n (newline from the enter press) on stdin that gets() picks up in the first iteration. This is not the nicest way to fix it, but to prove it write this line after that line:
int a = fgetc(stdin);
Check out a afterwards to confirm it has a newline.
Well, you probably get an empty string: when reading s you use formatted input which stops as soon as a non-digit is encountered, e.g., the newline used to indicate its input is finished. gets(), thus, immediately finds a newline, terminating the first string read.
That said, you shall never use gets(): It is a primary security problem and the root cause of many potential attack! You should, instead, use fgets() or, better, yet, std::getline() together with std::strings and a std::vector<std::string> >. Aslo, you should always verify that the attempt to input was successful:
if ((std::cin >> s).ignore(std::numeric_limits<std::streamsize>::max(), `\n`)) {
std::string line;
for (int i(0); i != s && std::getline(std::cin, line); ) {
A.push_back(line);
}
}
I'm trying to read character by character from a text file until EOF, put them into a character array, so that I can manipulate it after. Compiled with g++ without errors, and when run, I'm prompted for the input file but then it just hangs.
int main (int argc, char *argv[]) {
string filename;
ifstream infile;
char *cp, c[1024];
memset (c, 0, sizeof(c));
cp = c;
cout << "Enter file name: " << endl;
cin >> filename;
//open file
infile.open( filename.c_str() );
//if file can't open
if(!infile) {
cerr << "Error: file could not be opened" << endl;
exit(1);
}
while (!infile.eof()); {
infile.get(c, sizeof(infile));
// get character from file and store in array c[]
}
}//end main
You should try the istream::read() method rather than get(). This will help resolve any buffer overruns:
unsigned int chars_read = 0;
//...
// Read in the file.
if (!infile.read(c, sizeof(c))
{
// Handle the read error here.
// Also check for EOF here too.
}
// Obtain the number of characters actually read.
chars_read = infile.gcount();
First off, you don't want to test for eof()! Somehow I start to feel like Don Quixote having found my windmills. However, I do know that you need to check that the input was successful after trying to read it because before attempting to read the stream can't know whether it will be successful.
You program actually doesn't hang! It just waits for you to enter sizeof(infile) characters or end the input (e.g., using Ctrl-D on UNIXes and Ctrl-Z on Windows). Of course, this may look remarkable like a hanging program. You can verify that this is, indeed, the problem by using a smaller size, e.g., 4. Of course, sizeof(infile) is nearly as good as a small random number: It is the size of an object of type std::ifstream and who can tell what that is? You probably meant to use sizeof(c) to make sure that the call to get(c, n) won't write more character than can fit into c.
Try this:
int cont = 0;
while(infile.good()) {
c[cont++] = infile.get();
}
I am trying to display the text of a command line inputted text file line by line. But for some reason, it skips the first word in each line after the first line.
code:
using std::cout;
using std::cin;
using std::endl;
int main (int args, char* argv[])
{
char x[100];
char y[100];
char z[100];
cin.getline(x,100) >> argv[2];
cin.getline(y,100) >> argv[2];
cin.getline(z,100) >> argv[2];
cout << x <<endl;
cout << y <<endl;
cout << z <<endl;
return 1;
}
running ./a.out < moby.txt
displays this:
CHAPTER 1. Loomings.
me Ishmael. Some years ago--never mind how long precisely--having
or no money in my purse, and nothing particular to interest me on
but the first three lines in moby.txt is this:
CHAPTER 1. Loomings.
Call me Ishmael. Some years ago--never mind how long precisely--having
little or no money in my purse, and nothing particular to interest me on
The code is omitting "Call" and "little".
I feel like this is an \n error but i have no idea how to fix it.
Thanks in advance for any help.
cin.getline(x,100) >> argv[2];
You read a line (or the first 99 characters of the line) into x. Then you skip any whitespace and read the next word into argv[2]. The first words are ending up there.
Why are you using >> argv[2]? What are you possibly trying to do with this? argv[2] may not exist and even if it does, you don't have any control over the size of the character array pointed to by argv[2], so your chances of overrunning that array are quite high.
Rather than using char arrays directly for this, use std::getline with std::string to read lines into std::string objects: it is much easier to write correct code this way. For example,
std::string x;
if (!std::getline(std::cin, x)) {
// handle input error
}
#James McNellis has already pointed to the basic problem. My advice would be:
Don't use the member-function form of getline.
Don't mix getline and >> in the same statement.
Use a loop.
I find the other C++ getline to be easier and safer to use;
string str;
getline (cin,str);
will slurp the entire line and put it into a string, which you can then play with via the many fine string methods, or stringstream if you want to do I/O on parts of the string.
This is what I chose to do to make sure I am not missing any words or letters when I Use getline:
cout << "\nEnter some words: ";
while (getline(cin,myString)){
getline(cin,myString);
break;
};