I'm trying to get the beginning address of each line of my file as I read it, and print it out to the screen, but for some reason it just results in an endless loop. The file i'm reading is just a normal text file. Here's what I have going right now.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
int main(int argc, char* argv){
ifstream file;
string name, lnstr;
int addy;
if (argc > 1)
name = argv[1];
else
{
cout << "Please Enter Your Filename: ";
getline(cin, name);
}
file.open(name.data());
if(!file)
{
perror(name.data());
exit(1);
}
addy = 0;
while(getline(file, lnstr))
{
cout << file.seekg(addy, ios::beg) << endl;
addy++;
}
}
Even if I put 0 as the first parameter of seekg, it still results in an endless loop, or it just shows the same number a bunch of times. Not sure what i'm missing.
When you call ios::beg you set the position of the get pointer to the beginning of the file. You don't actually need this call and this code should work for you:
file.open(name.c_str()); // open file
if(file) {
while(getline(file, lnstr)) {
cout<< lnstr <<endl;
}
}
More on seekg.
I think you want tellg, not seekg.
Related
My task is to make a C++ program that will read, write, save, load and append a text file. I have two issues that I've been stuck on so far. The first being, how do you store the first argument entered by a user in a string using argv? Secondly, how do I create the program such that when the user enters in the command the program doesn't exit immediately after, so technically be in a while loop the whole time until prompted by a quit message? I've tried doing this already but my code also goes into a loop.
int main(int argc, char* argv[]) {
while (!inFile.eof()) {
inFile.open("userinput.txt");
getline(cin, line);
if (argc > 1) {
int result = strcmp(argv[1], "load");
if (result == 0) {
cout << "CORRECT" << endl;
}
else{
exit(1);
}
}
}
return 0;
}
Something like this, read program argument, read user input, read/write/append on a file.
#include <iostream>
#include <ios> // new
#include <fstream> // new
using namespace std;
int main(int argc, char* argv[])
{
fstream inFile("userinput.txt", std::ios_base::app | std::ios_base::out); //new, allows to append lines to 'userinput.txt'
while (!inFile.eof()) {
string line;
getline(cin, line);
inFile << line; // new: write the user input on inFile
if (argc > 1) {
int result = strcmp(argv[1], "load");
if (result == 0) {
cout << "CORRECT" << endl;
}
else {
exit(1);
}
}
}
return 0;
}
I don't really know the usage of this though so you should adapt it to your ends.
I have an issue with some code I have been working on. I am trying to read the contents of a text file (input.txt) into a variable fileContents. The loop in the code enters, but the program produces no output. Some of the variables are not used, I know about this. What is wrong?
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(int argc, char const *argv[])
{
ifstream input("input.txt");
ofstream output("output.txt"); //init output controller
// new lines will be skipped unless we stop it from happening:
//input.unsetf(std::ios_base::skipws);
// count the newlines with an algorithm specialized for counting:
unsigned line_count = std::count(std::istream_iterator<char>(input),std::istream_iterator<char>(), '\n');
string fileContents = ""; //init message, that will be filled by input.txt
string str; //temp string
while (input >> fileContents)
{
//cout << "loop entered";
cout << fileContents << "\n";
}
//cout << "test" << "\n";
return 0;
}
This is my code.
I am supposed to count the number of 'duck' in a txt file and print string like "There were 2 ducks in animals01.txt"
Now I get no error and nothing return.
Please tell me what's wrong?
#include <iostream> // for printf()
#include <cstdlib> // for exit(), perror()
#include <fstream> // for ifstream
using namespace std;
int main(int argc, char *argv[])
{
if (argc!=2) {
// if argc is not 2, print an error message and exit
cerr << "Usage: "<< argv[0] << " inputFile" << endl;
exit(1); // defined in cstdlib
}
return 0;
int num = 0;
ifstream ifs;
ifs.open(argv[1]);
string line;
do{
getline(ifs, line);
cout<<line<<endl;
if(line == "duck"){num++;}
}while(!ifs.eof());
cout<<"There were"<<num<<"ducks in"<<argv[1]<< endl;
}
You have the line return 0; before you actually did anything, and when you return main() the program is terminated.
By the way, don't use while(!ifs.eof()) because the eof flag only gets set at the first attempt to read past the end of the file, not when you read exactly to the end of the file due to a line break at the end. Do something like this. Also, fix your indenting as it is very misleading.
Read the file word by word.
Example:
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
string str, strToSearch = "ducks";
int wordCount = 0;
ifstream fin("thisfile.txt");
while (fin >> str) // Will read up to eof() and stop at every whitespace it hits. (like spaces!)
{
if(str==strToSearch)
wordCount++;
}
fin.close();
cout<<"There were"<<wordCount<<"ducks in thisfile.txt"<<endl;
return 0;
}
I have a text file of names. I want to read the text file into a stream, display it to the console. When it is done, it will prompt the user to enter their name. It should then add it to the file.
I can get it to do both of these things separately but not together.
Here is my code.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
using namespace System;
int main(array<System::String ^> ^args)
{
fstream myfile;
string line;
string name;
myfile.open("Names.txt",ios::out | ios::in | ios_base::app);
if (myfile.is_open())
{
while( getline(myfile, line) )
{
cout << line << endl;
}
cout << "Enter your name!\n";
getline (cin, name);
myfile << name;
myfile.close();
}
else
{
cout << "file was not opened\n";
}
return 0;
}
If I leave the while loop in there, it writes all the names to the console, but doesn't append the user entered name to the list. If I take out the while loop, I can add a name to the file but then of course I am not getting a list of the names that are already in that file.
My best guess is, I think it might have something to do with the fact that after I loop through the file using getline, The position is at the end of my stream, so when I try to add a name to it, there isn't any room left in the stream?
Your guess is correct.
The last call to getline() (the one that failed) set the error flags on your stream, which will fail any further IO attempts, which is why nothing is actually written in your file.
You can reset the errors flags with clear() after your reading loop :
myfile.clear();
Note:
You should also test for the returned value of your last getline() call.
Just bumped in to this issue and even though there is accepted answer here I think one can use full code that shows how to use canonical C++ file reading loop:
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
using namespace std;
using namespace System;
int main(array<System::String ^> ^args)
{
fstream myfile;
string line;
string name;
myfile.open("Names.txt",ios::out | ios::in | ios_base::app);
if (myfile.is_open())
{
while( getline(myfile, line) )
cout << line << endl;
if (file_list.eof())
file_list.clear(); //otherwise we can't do any further I/O
else if (file_list.bad()) {
std::cout << "Error occured while reading file";
return 1;
}
cout << "Enter your name!\n";
getline (cin, name);
myfile << name;
myfile.close();
}
else
{
cout << "file was not opened\n";
}
return 0;
}
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (int argc, char* argv[])
{
string STRING;
ifstream infile;
STRING = argv[1];
infile.open(argv[1]);
if (infile.fail())// covers a miss spelling of a fail name
{
cout << "ERROR. Did you make a mistake in the Spelling of the File\n";
return 1;
}
else
{
while(!infile.eof())
{
getline(infile,STRING); // Get the line
cout<<STRING + "\n"; // Prints out File line
}
infile.close();
return 0;
}
}
I have got this program working fine apart from one problem
if the user only runs the program with no file name (what I believe to be called arguments) e.g ./displayfile then I get a Segmentation fault
How would I amend my code so that the program would exit with an error message along the lines of "Add a file name"
My first thought is something along the lines of
if (!argc=2)
{
cout << "ERROR. Enter a file name";
return 1;
}
ADDED:
just in case this matters am compiling using
g++ displayfile.cpp -o displayfile
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (int argc, char* argv[]) {
if(argc != 2) {
cout << "You need to supply one argument to this program.";
return -1;
}
string STRING;
ifstream infile;
STRING = argv[1];
infile.open(argv[1]);
if (infile.fail())// covers a miss spelling of a fail name {
cout << "ERROR. Did you make a mistake in the Spelling of the File\n";
return 1;
}
else {
while(!infile.eof()) {
getline(infile,STRING); // Get the line
cout<<STRING + "\n"; // Prints out File line
}
infile.close();
return 0;
}
}
Besides the obvious check for argc != 2 I couldn't help fixing some of the worse code and the obvious error:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (int argc, char* argv[])
{
if (argc != 2)
{
cout << "ERROR. Invalid number of arguments\n";
return 1;
}
ifstream infile(argv[1]);
if (!infile) // covers a miss spelling of a fail name
{
cout << "ERROR. Did you make a mistake in the Spelling of the File\n";
return 1;
}
string STRING;
while(getline(infile, STRING))
cout << STRING << '\n'; // Prints out file line
return 0;
}
You don't need to call ifstream::open, just use the constructor, likewise don't you need to declare STRING so early and neither to initialize it to the file name, since you don't use it. Don't forget, this is not C, you don't need a whole mess of declarations at the beginning of each function.
Second, checking for the flags of a stream is often a bad idea, just check for !infile to find any errors. But the real error is in checking for infile.eof in the while condition, since it only gets set once getline has tryed to read over the end of the file, so you would actually print one (probably empty) line too much. Just check for getline's return value to find any errors or the end of file.
And don't add the newline onto the string when outputting, just put it out after the string. And last but not least, no need for infile.close, since the destructor calls it anyway.
change STRING = argv[1]; to if (argv[1] != null) STRING = argv[1]; not sure though, so you'll have to test it out first.