I've made a static ifstream object inside a function and I'm associating it with the file given in the function argument.
In the main function, I'm calling this function twice, each time with a different file name.
Here's my code:
#include <iostream>
#include<fstream>
using namespace std;
void print_file(string path)
{
static ifstream ifs{path.c_str()};
if (ifs.is_open())
{
cout<<endl<<"Going to print the file: "<<endl;
char c = ifs.get();
while (ifs.good()) {
std::cout << c;
c = ifs.get();
}
}
else
cout<<endl<<"File couldn't be opened"<<endl;
}
int main(int argc, char**argv)
{
if(argc!=3)
{
cout<<endl<<argv[0]<<" file_name1 file_name2"<<endl;
return 0;
}
print_file(argv[1]);
print_file(argv[2]);
}
Given below is the output:
[vishal1#localhost temp]$ ./exe file1.txt file2.txt
Going to print the file:
File 1 contents
Going to print the file:
Due to some reasons file1 is not getting printed the second time. What's the reason?
The reason is that in the first call you read all the contents of the file, but you're not resetting the read file pointer to the beginning. So the next call the file status is still and the end of the file and ifs.good() returns false.
You need to "rewind" the file, and clear the status flags.
Also note that you should never use eof() in a loop condition, and using good() is just the same.
In your case, use e.g.
while (ifs.get(c))
{
std::cout << c;
}
instead.
Related
I want to create multiple files inside a loop and write something into them. I have made the following code. But it only creates one file named '1' instead of five files (from 1 to 5):
#include <fstream>
#include<iostream>
using namespace std;
int main(){
FILE *fp;
ofstream os;
char i;
char fileName[] = "0.txt";
for(i='1';i<='5';i++)
{
fileName[0]=i;
.
os.open (fileName);
os<<"Hello"<<"\n";
}
}
Is there anything wrong in the code? How will I get the five files?
The reference for std::ofstream::open specifically states:
Open file Opens the file identified by argument filename, associating
it with the stream object, so that input/output operations are
performed on its content. Argument mode specifies the opening mode.
If the stream is already associated with a file (i.e., it is already
open), calling this function fails.
You never close the file you're working with in your loop so open for the second-fifth time fails.
add it:
for(i='1';i<='5';i++)
{
fileName[0]=i;
os.open (fileName);
os<<"Hello"<<"\n";
os.close();
}
Also, you should check if open() succeeded:
for(i='1';i<='5';i++)
{
fileName[0]=i;
os.open (fileName);
if(os) // checks if open() succeeeded
{
os<<"Hello"<<"\n";
os.close();
}
}
#include <fstream>
#include <iostream>
using namespace std;
int main() {
ofstream os;
char fileName[] = "0.txt";
for(int i = '1'; i <= '5'; i++)
{
fileName[0] = i;
os.open(fileName);
os << "Hello" << "\n";
os.close();
}
}
I created a data file called program.txt. I need to create code that prints out number of lines and integer values from that program.txt
Heres the text I made
1
35
45
87
9
100
the program.text has these values in it
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string calc;
int test;
int cool;
int book;
ifstream myfile;
ifstream outof;
myfile.open ("program.txt");
outof.open("program.txt");
if (myfile.fail())
{
cerr<<"Error Opening file"<<endl;
}
if(outof.fail ())
{
cerr<<"Error Opening file"<<endl;
}
while (!myfile.eof ())
{
getline(myfile,calc);
++book;
}
cout <<book<<endl;
while (!outof.eof ())
{
outof<<test;//
cool++;
}
cout<<cool<<endl;
myfile.close();
outof.close();
}
Also after cerr I tried exit (1) and it said exit was not defined.
I am new to this any help would be greatly appreciated. Thanks This is C++ btw.
The problem is that you are using ifstream, which stands for INPUT file stream. You want to use ofstream, which is OUTPUT file stream. You cannot write to an input file stream, hence why the << operator is not defined.
Also, rather than using exit(1) after your errors, you can just return 1; as you are inside your main function. This will terminate the program, returning 1 as the exit code.
If you really want to use exit, you need to #include <cstdlib>.
Your defined input and expected output aren't clearly defined, so I'm not sure what you're trying to do. However, here's a general idea:
Putting the filename in a fstream's constructor will automatically try to open the file for read/write. You dont need to call .open() anymore. Also, you shouldnt be reading and writing to the same file simultaneously if you dont know what you're doing.
std::ifstream myInputFile("program.txt");
std::ofstream myOutputFile("programOut.txt");
Rather than checking myInputFile.fail(), just use the overloaded boolean operator. In depth explanation: ifstream::is_open vs ifstream::fail?
if (!myInputFile) {
//Something went wrong
std::cerr << "Failed to open input file" << std::endl;
return 1;
}
Define your std::string to hold lines as you read them, read all of your input file, and count the lines.
std::string line;
int lineCount = 0;
while (getline(myInputFile,line)) {
++lineCount;
//Do something with 'line'
}
Maybe you'll need to store the lines from your input file so that you can output the count of the lines at the beginning of your output file, you might want to #include <vector> and do something like this:
std::string line;
std::vector<std::string> linesFromFile;
//Read in all lines of the input file and store them in the vector
while (getline(myInputFile, line)) {
linesFromFile.emplace_back(line);
}
//All lines read, good time to close input file
myInputFile.close();
//Print number of lines read
myOutputFile << linesFromFile.size() << std::endl;
//Loop through lines and print them
for (auto &lineFromFile : linesFromFile) {
myOutputFile << lineFromFile << std::endl;
}
//Done outputting, close output file
myOutputFile.close();
The following code is part of a larger translator program. The code below asks the user to type a line and than just writes it back. Is there a way that instead of writing a single line each time, I can just pass in a whole file etc 'translate.txt' in standard input and the program can write it back line by line and produces an error when the end of line is reached ?
#include <iostream>
#include <string.h>
#include<stdio.h>
#include<fstream>
using namespace std;
using namespace std;
void PL() {
char line[BUFSIZ];
while( cin.good() ) {
cout<<"Type line now"<<endl;
cout<<"\n";
cin.getline(line, sizeof(line));
cout<<"\n"<<endl;
string mystring = string(line);
// supposed to Parsing string into words and translate//
//but just reading back input for now//
cout<<"You typed:"<<mystring<<endl;
cout<<"\n"<<endl;
}
}
int main() {
PL();
}
Do you expect a way to pass a file to your program?
executable < file
This code works well for me:
void PL() {
string line;
while(cin) {
cout<<"Type line now";
if(std::getline(cin,line)) {
// supposed to Parsing string into words and translate//
//but just reading back input for now//
cout<<"You typed:"<<line<<endl;
}
}
}
Note that the stdin there is actually passed to the program from the shell as mentioned:
$ executable < file
If you want to pass arbitrary types of streams created from outside this function, you'll need something like
void PL(std::istream& is) {
string line;
while(is) {
cout<<"Type line now";
if(std::getline(is,line)) {
// supposed to Parsing string into words and translate//
//but just reading back input for now//
cout<<"You typed:"<<line<<endl;
}
}
}
int main() {
std::ifstream is("mytext.txt"); // hardcoded filename
PL(is);
return 0;
}
or alternatively
int main(int argc, char* argv[]) {
std::istream* input = &std::cin; // input is stdin by default
if(argc > 1) {
// A file name was give as argument,
// choose the file to read from
input = new std::ifstream(argv[1]);
}
PL(*input);
if(argc > 1) {
// Clean up the allocated input instance
delete input;
}
return 0;
}
There are certainly more elegant solutions
and calling from the command line:
$ executable mytext.txt
Your shell will have a way to pass a file in over stdin. So for example, if you are on a bourne-compatible shell you can run
translate < translate.txt
(assuming your program is compiled to a binary named translate). This is assuming you want to start the program interactively, i.e. from a shell.
If you want to automatically spawn this program from another program you wrote, it depends on your OS. On POSIX operating systems, for example, you will want to open the file and dup2 the resulting file descriptor into STDIN_FILENO after forking but before calling one of the exec family functions.
I'am having a rather difficult time with this program (see code below). It is supposed to :
Create an array of 26 components to do the letter count for the 26 letters in the alphabet and a variable for the line count.
Create an ASCII (or text) file that contains text and will be used as input to my program.
Call that file "textinput" and then, have the output stored in a file called "textoutput".
Can anyone tell me what I'am doing wrong? I keep getting "File not found" errors.
#include <iostream>
#include <cstdio>
#include <iomanip>
#include <cstdlib>
#include <fstream>
using namespace std;
int main()
{
int lineCount = 0;
int letterCount[26];
for(int i = 0; i < 26; i++)
letterCount[i] = 0;
ifstream infile;
infile.open("textinput.txt", ios::in);
if(!infile)
{
cerr<<"File does not exist."<<endl;
exit(1);
}
ofstream outfile;
outfile.open("textoutput.txt", ios::out|ios::binary);
if(!outfile)
{
cerr<<"File cannot be opened."<<endl;
exit(1);
}
char data[100];
outfile<<data;
while(infile>>data)
{
outfile<<data<<endl;
}
while(infile)
{
char ch1 = infile.get();
if(ch1 == '\n')
{
lineCount++;
continue;
}
int asciiNum = (int)ch1;
if(asciiNum > 96)
{
asciiNum = asciiNum - 97;
}
else
{
asciiNum = asciiNum - 65;
}
letterCount[asciiNum]++;
}
infile.close();
outfile.close();
system("PAUSE");
return 0;
}
The funny thing is, "File not found" errors are not possible with your program.1 So, I'm going out on a limb and suggest that you need to qualify the path to your executable!
Say, you compiled with something like
gcc program1.cpp -o program1
To execute, you must use
./program1
Because program1 won't work. The reason is that with 99% certainty, your current working directory is not in the search PATH for executables (and you want to keep it that way).
Beyond this, yes, do make sure that the textinput.txt exists in the same directory.
1(There's no such error message in the program. You should know: you programmed it!)
ifstream class is used to read from files and to read from files you must need to create it first which you haven't done, so first create the file .
By doing like this :
ifstream infile;
infile.open("textinput.txt", ios::in);
you are trying to read from a file which has not been created yet OR may be as described in other answer or the comments that your file doesn't exist in the same directory.
You better use ofstream to first write on the file and then use ifstream.
Does your code work if you have the file? If it does try removing the ios::out.If i'm not mistaken ios::out is used when you do not want to truncate your old content in the file,but that implies you already have it.
I have built a .cpp program in order to write some content to a .txt file created within the .cpp file.
I manage to write the desired content, however, when I am trying to open the created file from terminal, it says that it cannot find it although it is there.
When I try to open it with vi or nano it's content it's empty. It is like creating a new file.
However, when I open it outside terminal, I can see its content as I wanted.
What could be the problem and how can I fix this situation?
Bellow, I have added the code.
The problem is with the system(buffer) command. I receive the following error: sh: cannot open video2.txt: No such file. I have tried to opened the files from command prompt and I get the above described situation.
int main(int argc,char* argv[])
{
fstream RawStipFile;
RawStipFile.open(strcat(argv[1],".txt"));
string line;
if (RawStipFile.is_open())
{
getline(RawStipFile, line);
int i = 0;
ofstream OutVideoStip;
ofstream VideoList;
VideoList.open("VideoList.txt");
while ( RawStipFile.good() )
{
getline (RawStipFile,line);
char* l;
l = (char*) malloc(sizeof(char));
l[0]=line[0];
//cout<<line[0]<<endl;
if (line[0]==35)
{
if (OutVideoStip.is_open())
{
OutVideoStip.close();
}
i++;
//char* base;
//base = (char*) malloc(1000*sizeof(char));
//sprintf(base, "%d", i);
char* b;
b = &line[1];
VideoList<<b<<endl;
OutVideoStip.open(strcat(b, ".txt"));
}
else
{
OutVideoStip << line << endl;
}
}
OutVideoStip.close();
RawStipFile.close();
VideoList.close();
}
else
{
cout << "Unable to open file \n";
}
fstream VideoNames;
VideoNames.open("VideoList.txt", fstream::in);
if (VideoNames.is_open())
{
while ( VideoNames.good() )
{
getline(VideoNames, line);
line=line.substr(1,line.length());
if (line.compare(""))
{
string initial = "./txt2mat<";
initial.append(line);
initial.append(".txt>");
initial.append(line);
initial.append(".dat");
cout<<initial<<endl;
const char* buffer;
buffer = initial.c_str();
system(buffer);
}
}
}
else
{
cout<<"Unable to open file. \n";
}
VideoNames.close();
return 0;
}
You are using strcat in a wrong way. I don't know if that's the cause of your problem, but it can result in undefined behavour;
int main(int argc,char* argv[])
{
fstream RawStipFile;
RawStipFile.open(strcat(argv[1],".txt"));
Here you modify argv[1]. You append 4 characters to it, without allocating any memory.
string line;
...
char* b;
b = &line[1];
VideoList<<b<<endl;
OutVideoStip.open(strcat(b, ".txt"));
a string takes care of it's own memory management. You can't asume it has reserved 4 more bytes for you to append. If you need to append, use string member functions, not strcat.
just a loose guess: the current working directory is not the same?
Try either using chdir first or opening by absolute path /home/simon/VideoList.txt