I am writing a simple program to take in two files. The terminal command line looks like this.
./fileIO foo.code foo.encode
When it runs, the second file is not read in. When I enter
./fileIO foo.code foo.code
it works. I can't seem to figure out why the second one is not opening. Any ideas? Thanks!
#include <fstream>
#include <iostream>
#include <queue>
#include <iomanip>
#include <map>
#include <string>
#include <cassert>
using namespace std;
int main( int argc, char *argv[] )
{
// convert the C-style command line parameter to a C++-style string,
// so that we can do concatenation on it
assert( argc == 3 );
const string code = argv[1];
const string encode = argv[2];
string firstTextFile = code;
string secondTextFile = encode;
//manipulate the first infile
ifstream firstFile( firstTextFile.c_str(), ios::in );
if( !firstFile )
{
cerr << "Cannot open text file for input" << endl;
return 1;
}
string lineIn;
string codeSubstring;
string hexSubstring;
while( getline( firstFile, lineIn ) )
{
hexSubstring = lineIn.substr(0, 2);
codeSubstring = lineIn.substr(4, lineIn.length() );
cout << hexSubstring << ", " << codeSubstring << endl;
}
//manipulate the second infile
ifstream secondFile( secondTextFile.c_str(), ios::in );
if( !secondFile )
{
cerr << "Cannot open text file for input" << endl;
return 1;
}
char characterIn;
while( secondFile.get( characterIn ) )
{
cout << characterIn << endl;
}
return 0;
}
One thing you might want to try is adding the close() call as is standard procedure after you're done using files. Sometimes issues arise with re-opening files if they were not closed properly in a previous run.
firstFile.close();
secondFile.close();
Also, you may try restarting the computer if there is some lingering file handle that hasn't been released.
Related
I've written this code, which it get the repository and look for the files within. it aims to create binary files for each file found so as to write some data inside it later. However, the code is not running as expected. and the binary file are not created this the issue.
the directory has two images, and the output I get is as follows :
Creating bin files
C:\repo\1.bin
Error: failed to create file
Press <RETURN> to close this window...
I really do not know where I miss it. Any advice I'd be glad.
#include <vector>
#include <string>
#include <iostream> // for standard I/O
#include <string> // for strings
#include <iomanip> // for controlling float print precision
#include <sstream> // string to number conversion
#include <fstream>
using namespace std;
void getDir(string d, vector<string> & f)
{
FILE* pipe = NULL;
string pCmd = "dir /B /S " + string(d);
char buf[256];
if( NULL == (pipe = _popen(pCmd.c_str(),"rt")))
{
cout<<"Error"<<endl;
return;
}
while (!feof(pipe))
{
if(fgets(buf,256,pipe) != NULL)
{
f.push_back(string(buf));
}
}
_pclose(pipe);
}
void replaceExt(string& s, const string& newExt) {
string::size_type i = s.rfind('.', s.length());
if (i != string::npos) {
s.replace(i+1, newExt.length(), newExt);
}
}
using namespace std;
int main(int argc, char* argv[])
{
vector<string> files;
string path = "C:\\repo";
getDir(path, files);
vector<string>::const_iterator it = files.begin();
cout<<"Creating bin files "<<endl;
ofstream myOfstream;
while( it != files.end())
{
string fileName = (string) *it;
replaceExt(fileName, "bin");
cout << fileName << '\n';
std::stringstream ss;
ss << fileName << "" ;
myOfstream.open(ss.str(), fstream::binary);
if ( !myOfstream )
{
std::cerr << "Error: failed to create file " << '\n';
break;
}
myOfstream.close();
it++;
}
return 0;
}
First I have to say, if you directory you are looking for doesn't exists or is empty, the program gets locked, it would be nice to have that fixed if making a bigger program.
Then, for your case, I don't see whars the point of that stringstream, so I tried removing that, and changing it by a normal string, removing the last \n character you get from reading the filenames:
cout << fileName << '\n';
string ss = fileName.substr(0, fileName.size() - 1);
myOfstream.open(ss.c_str(), fstream::binary);
if (!myOfstream)
{
hope it helps
I found the issue bro, after debugging ;D
the problem is in the "newline", the string fileName has a "\n" at the end that's whats rise your error. Thus you have to erase it, I ve used this statement fileName.erase(std::remove(fileName.begin(), fileName.end(), '\n'), fileName.end());
and I included algorithm lib.
the working code is as follows :
#include <vector>
#include <string>
#include <iostream> // for standard I/O
#include <string> // for strings
#include <iomanip> // for controlling float print precision
#include <sstream> // string to number conversion
#include <fstream>
#include <algorithm>
using namespace std;
void getDir(string d, vector<string> & f)
{
FILE* pipe = NULL;
string pCmd = "dir /B /S " + string(d);
char buf[256];
if( NULL == (pipe = _popen(pCmd.c_str(),"rt")))
{
cout<<"Error"<<endl;
return;
}
while (!feof(pipe))
{
if(fgets(buf,256,pipe) != NULL)
{
f.push_back(string(buf));
}
}
_pclose(pipe);
}
void replaceExt(string& s, const string& newExt) {
string::size_type i = s.rfind('.', s.length());
if (i != string::npos) {
s.replace(i+1, newExt.length(), newExt);
}
}
using namespace std;
int main(int argc, char* argv[])
{
vector<string> files;
string path = "C:\\repo";
getDir(path, files);
vector<string>::const_iterator it = files.begin();
cout<<"Creating bin files "<<endl;
ofstream myOfstream;
while( it != files.end())
{
string fileName = (string) *it;
replaceExt(fileName, "bin");
cout << fileName << '\n';
fileName.erase(std::remove(fileName.begin(), fileName.end(), '\n'), fileName.end());
std::stringstream ss;
ss << fileName << "" ;
myOfstream.open(ss.str(), fstream::binary);
if ( !myOfstream )
{
std::cerr << "Error: failed to create file " << '\n';
break;
}
myOfstream.close();
it++;
}
return 0;
}
I feel like I've tried everything, I can get the first file to append to the second but cannot get the second file into a third. What am I doing wrong?
To be clear I need to take one file, append it to a second file, then put the contents of that second file into a third. I was able to simulate this outcome by putting both files into strings and then putting those strings into a third file, but that's not 'correct' in this problem.
I'm not particular to any way or any technique, I've tried a few and nothing works. This is the latest attempt, still doesn't work for the last step.
Here's my code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string a,b,c;
cout << "Enter 3 file names: ";
cin >> a >> b >> c;
fstream inf;
ifstream two;
fstream outf;
string content = "";
string line = "";
int i;
string ch;
inf.open(a, ios::in | ios:: out | ios::app);
two.open(b);
outf.open(c, ios::in);
//check for errors
if (!inf)
{
cerr << "Error opening file" << endl;
exit(1);
}
if (!two)
{
cerr << "Error opening file" << endl;
exit(1);
}
if (!outf)
{
cerr << "Error opening file" << endl;
exit(1);
}
for(i=0; two.eof() != true; i++)
content += two.get();
i--;
content.erase(content.end()-1);
two.close();
inf << content;
inf.clear();
inf.swap(outf);
outf.close();
inf.close();
return 0;
Here's an idea:
#include <fstream>
using namespace std;
void appendf( const char* d, const char* s )
{
ofstream os( d, ios::app );
if ( ! os )
throw "could not open destination";
ifstream is( s );
if ( ! is )
throw "could not open source";
os << is.rdbuf();
}
int main()
{
try
{
appendf( "out.txt", "1.txt" );
return 0;
}
catch ( const char* x )
{
cout << x;
return -1;
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have a text file that consists of "funny" non-ASCII characters such as NUL, RS, CAN all in a black square. When I read the file line by line, it just stops each line where one of these appear.
All I want to do is to copy the same file only without these characters.
How to do that?
Let's say you are reading the file line by line and write the output to a different file like this:
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
string inPath("a.txt");
string outPath("b.txt");
string line;
ifstream in(inPath.c_str(), ifstream::in | ifstream::binary);
if ( ! in.is_open() ) {
cerr << "Error: Failed to read file \"" << inPath << "\"." << endl;
return EXIT_FAILURE;
}
ofstream out(outPath.c_str(), ofstream::out | ofstream::binary);
if ( ! out.is_open() ) {
cerr << "Error: Failed to write file \"" << outPath << "\"." << endl;
return EXIT_FAILURE;
}
while ( getline(in, line) ) {
out << line;
}
cout << "Done." << endl;
return EXIT_SUCCESS;
}
The problem is that the input stream gets interpreted if not opened in binary mode. That means all control characters (the ones you see in Notepad++ for example in black boxes) are not handled as ordinary characters but in a special way.Depending on the library implementation the read operation may just stop, ignore those characters, convert them into different character sequences or tread them in their special way (like as end of text mark for example).You can check if a characters is a control character with iscntrl() for example.To remove these characters in every line you can use the following code:
#include <algorithm>
#include <cstdlib>
#include <cctype>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
string inPath("a.txt");
string outPath("b.txt");
string line;
ifstream in(inPath.c_str(), ifstream::in | ifstream::binary);
if ( ! in.is_open() ) {
cerr << "Error: Failed to read file \"" << inPath << "\"." << endl;
return EXIT_FAILURE;
}
ofstream out(outPath.c_str(), ofstream::out | ofstream::binary);
if ( ! out.is_open() ) {
cerr << "Error: Failed to write file \"" << outPath << "\"." << endl;
return EXIT_FAILURE;
}
while ( getline(in, line) ) {
/* this also removes line-feed and carrier-return */
line.erase(remove_if(line.begin(), line.end(), ::iscntrl), line.end());
out << line << '\n';
}
cout << "Done." << endl;
return EXIT_SUCCESS;
}
you can loop through each char in the file and use utility functions like isalpha(), isalnum() and isdigit() to make sure each char is is ascii, and skip out the others.
see http://www.cplusplus.com/reference/cctype/isalpha/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string>
using std::string;
int die(string &msg) {
fprintf(stderr, "%s\n", msg.c_str());
exit(-1);
return -1; // Not really.
}
int
main(int argc, char **argv) {
string msg;
string inpt;
FILE *INPT;
string oupt;
FILE *OUPT;
int c;
(argc > 1) ||
(die(msg += "Missing filename arg."));
inpt += argv[1];
(oupt += inpt) += ".nxt";
(INPT = fopen(inpt.c_str(), "r")) ||
(die(((msg += "Can't open \"") += inpt) += "\" for input."));
(OUPT = fopen(oupt.c_str(), "w")) ||
(die(((msg += "Can't open \"") += oupt) += "\" for output."));
for (;(c = fgetc(INPT)) != EOF;) {
((unsigned)c < 0x80u) &&
(
(isprint(c)) ||
((iscntrl(c)) && (isspace(c)))
) &&
(fputc(c, OUPT));
}
fclose(OUPT);
fclose(INPT);
return 0;
}
I'm trying to create a program that passes a file to a function. The function is supposed to detect how many lines are in my file. I don't think I'm passing the file correctly into my function, I've tried several different ways. Any help will be greatly appreciated.
#include <iostream>
#include <fstream>
#define die(errmsg) {cerr << errmsg << endl; exit(1);}
using namespace std;
int num_of_lines(ifstream file)
{
int cnt3;
string str;
while(getline(file, str))cnt3++;
return(cnt3);
}
int main(int argc, char **argv)
{
int num_of_lines(ifstream file);
string file;
file = argv[1];
if(argc == 1)die("usage: mywc your_file"); //for some reason not working
ifstream ifs;
ifs.open(file);
if(ifs.is_open())
{
int a;
cout << "File was opened\n";
a = num_of_lines(file);
cout <<"Lines: " << a << endl;
}
else
{
cerr <<"Could not open: " << file << endl;
exit(1);
}
ifs.close();
return(0);
}
Two problems with the function. First, you should pass the stream by reference. Second, you just forgot to initialise your counter.
int num_of_lines( ifstream &file )
{
int cnt3 = 0;
string str;
while( getline(file, str) ) cnt3++;
return cnt3;
}
The other thing is you're passing file to it (which is a string) instead of ifs. Change the call to:
a = num_of_lines( ifs );
I have to write a program that will go through a given folder and use regex_search to find every instance of a certain string. I've got the regex_search working on it's own now, and I'm just trying to figure out how to go through each file. I want to attempt it using directory but am unsure where I would put it. Would I have to put the search through the file into my main method or would I have to create a seperate function outside of the main method for going through each file and call on it within the main method?
This is what I have now. Any tips you guys can give on how to approach this would be greatly appreciated!
Right now the function of it is to read an input text file and output a txt file that shows all the instances and the line number of each apperance. I am not required to see which lines they are on, use a particular file, or make an output file for this program, what I find will simply be printed to the console. I've left what I have now because I'm not sure if I'll checking each indivdual file in a similar fashion just with a different cariable name.
#include <iostream>
#include <regex>
#include <string>
#include <fstream>
#include <vector>
#include <regex>
#include <iomanip>
using namespace std;
int main (int argc, char* argv[]){
// validate the command line info
if( argc < 2 ) {
cout << "Error: Incorrect number of command line arguments\n"
"Usage: grep\n";
return EXIT_FAILURE;
}
//Declare the arguments of the array
string resultSwitch = argv[1];
string stringToGrep = argv[2];
string folderName = argv [3];
regex reg(stringToGrep);
// Validate that the file is there and open it
ifstream infile( inputFileName );
if( !infile ) {
cout << "Error: failed to open <" << inputFileName << ">\n"
"Check filename, path, or it doesn't exist.\n";
return EXIT_FAILURE;
}
while(getline(infile,currentLine))
{
lines.push_back( currentLine );
currentLineNum++;
if( regex_search( currentLine, reg ) )
outFile << "Line " << currentLineNum << ": " << currentLine << endl;
}
infile.close();
}
Reading a directory/folder is operating system dependent. In a UNIX/Linux/MacOS world, you use opendir(), and readdir():
#include <sys/types.h>
#include <dirent.h>
...
DIR *directory = opendir( directoryName );
if( directory == NULL )
{
perror( directoryName );
exit( -2 );
}
// Read the directory, and pull in every file that doesn't start with '.'
struct dirent *entry;
while( NULL != ( entry = readdir(directory) ) )
{
// by convention, UNIX files beginning with '.' are invisible.
// and . and .. are special anyway.
if( entry->d_name[0] != '.' )
{
// you now have a filename in entry->d_name;
// do something with it.
}
}