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;
}
Related
#include <iostream>
#include <string>
#include <stdio.h>
#include <cstring>
#include <fstream>
#include <vector>
#include <iterator>
using std::cout;
using std::cin;
using std::endl;
using std::string;
std::string FilesOpen(std::string command)
{
const int size_buffer = 2;
char buffer[size_buffer];
memset(buffer, 0, size_buffer * sizeof(char));
std::string result = "";
// Open pipe to file
FILE* pipe = popen(command.c_str(), "r");
if (!pipe)
{
return "popen failed!";
}
// read till end of process:
while (!feof(pipe))
{
// use buffer to read and add to result
if (fgets(buffer, 2, pipe) != NULL)
{
result += buffer;
memset(buffer, 0, size_buffer * sizeof(char));
}
}
pclose(pipe);
return result;
}
int main(int* agrc, char* agrv[])
{
std::vector<std::string> pole;
std::string text;
// get files names and use to ifstream files
FilesOpen("ls /root/workspace/src/server > /root/workspace/filestext.txt");
// get files info size and names
FilesOpen("ls -l /root/workspace/src/server > /root/workspace/filelist.txt");
// get files name and add vector
std::ifstream files;
files.open("/root/workspace/filestext.txt", std::ios_base::in);
if (!files)
{
std::cout << "Error not open files" << std::endl;
}
while (files >> text)
{
pole.push_back(text);
}
files.close();
for (std::vector<std::string>::iterator it = pole.begin(); it != pole.end(); ++it)
{
std::cout << *it << std::endl;
}
// replace text in shell
std::string filereplace = "/root/workspace/testovaci.sh";
std::ofstream r_file(filereplace.c_str());
char patch[] = "patch=";
if (r_file.is_open())
{
for (int i = 0; patch[i] != '\0'; i++)
r_file.put(patch[i]);
r_file.put('D');
}
r_file.close()
}
I need to get the contents of the file name from the filetext.txt file and ignore the folders and list them in the testovaci.sh script, which looks like this:
neco1
neco2
neco3
patch =
neco4
neco5
I need to put in the testovaci.sh file has been added to patch = "file". "file". "file"
and the folders were ignored, leaving only binary files.
Please help me, as I tried everything but nothing works.
im trying to make a simple program that list all txt file in the directory then append hello world in them but i face an issue while passing the vector into WriteFiles Function
this is the following code i've tried to fix it for a while any oil be grateful for any help
#define _CRT_SECURE_NO_WARNINGS
#include <string>
#include <vector>
#include <iostream>
#include <windows.h>
#include <fstream>
using namespace std;
void ListFiles(vector<string>& f) // list all files
{
FILE* pipe = NULL;
string pCmd = "dir /b /s *.txt ";
char buf[256];
if (NULL == (pipe = _popen(pCmd.c_str(), "rt")))
{
return;
}
while (!feof(pipe))
{
if (fgets(buf, 256, pipe) != NULL)
{
f.push_back(string(buf));
}
}
_pclose(pipe);
}
void WriteFiles (const char* file_name)
{
std::ofstream file;
file.open(file_name, std::ios_base::app); // append instead of overwrite
file << "Hello world";
file.close();
}
int main()
{
vector<string> files;
ListFiles(files);
vector<string>::const_iterator it = files.begin();
while (it != files.end())
{
WriteFiles(*it); // the issue is here
cout << "txt found :" << *it << endl;
it++;
}
}
WriteFiles(it->c_str()); will fix the problem. Iterators act a lot like pointers, so that's how you access a method indirectly.
I'm reading files in a directory and passing it to a function, I think I'm doing it in a wrong way, not able to figure out.
Here is my code first it reads files in a folder and send it to a function for further operations.
#include <dirent.h>
#include <stdio.h>
#include <vector>
#include <string>
#include <iostream>
using namespace std;
std::vector<std::string> fileName;
int main(void)
{
DIR *d;
struct dirent *dir;
vector<string> fileList;
int i=0;
d = opendir("files");
if (d)
{
while ((dir = readdir(d)) != NULL)
{
i++;
fileList.push_back(dir->d_name);
}
for(int i=0;i<fileList.size();i++) {
cout<<fileList[i]<<endl;
doSomething(fileList[i]);
}
closedir(d);
}
return(0);
}
int doSomething(fileName) {
//do something
}
Error
main.cpp: In function ‘int main()’:
main.cpp:29:28: error: ‘doSomething’ was not declared in this scope
doSomething(fileList[i]);
^
main.cpp: At global scope:
main.cpp:37:26: error: cannot convert ‘std::vector<std::basic_string<char> >’ to ‘int’ in initialization
int doSomething(fileName) {
^
main.cpp:37:28: error: expected ‘,’ or ‘;’ before ‘{’ token
int doSomething(fileName) {
^
Since your doSomething function is defined after main, it is not visible, that causes the first error. The correct way would be to at least declare the function first:
int doSomething(); //declaration
int main()
{
doSomething(); //now the function is declared
}
//definition
int doSomething()
{
}
Now, the second and third errors is emited because you didn't include the fileName parameter's type in your function definition. Based on your code, it should be a string:
int doSomething(string fileName)
{
}
I also noticed that, while this function returns int, you are not using it's returned value. Nevertheless, don't forget to return something from doSomething, otherwise it will cause undefined behavior.
Yes, Boost is great, but it's a bit bloaty. So, just for completenessapplied to reading images in a directory for OpenCV:
// you need these includes for the function
//#include <windows.h> // for windows systems
#include <dirent.h> // for linux systems
#include <sys/stat.h> // for linux systems
#include <algorithm> // std::sort
#include <opencv2/opencv.hpp>
#include <iostream> //cout
using namespace std;
/* Returns a list of files in a directory (except the ones that begin with a dot) */
int readFilenames(std::vector<string> &filenames, const string &directory)
{
#ifdef WINDOWS
HANDLE dir;
WIN32_FIND_DATA file_data;
if ((dir = FindFirstFile((directory + "/*").c_str(), &file_data)) == INVALID_HANDLE_VALUE)
return; /* No files found */
do {
const string file_name = file_data.cFileName;
const string full_file_name = directory + "/" + file_name;
const bool is_directory = (file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
if (file_name[0] == '.')
continue;
if (is_directory)
continue;
filenames.push_back(full_file_name);
} while (FindNextFile(dir, &file_data));
FindClose(dir);
#else
DIR *dir;
class dirent *ent;
class stat st;
dir = opendir(directory.c_str());
while ((ent = readdir(dir)) != NULL) {
const string file_name = ent->d_name;
const string full_file_name = directory + "/" + file_name;
if (file_name[0] == '.')
continue;
if (stat(full_file_name.c_str(), &st) == -1)
continue;
const bool is_directory = (st.st_mode & S_IFDIR) != 0;
if (is_directory)
continue;
// filenames.push_back(full_file_name); // returns full path
filenames.push_back(file_name); // returns just filename
}
closedir(dir);
#endif
std::sort (filenames.begin(), filenames.end()); //optional, sort the filenames
return(filenames.size()); //Return how many we found
} // GetFilesInDirectory
void help(const char **argv) {
cout << "\n\n"
<< "Call:\n" << argv[0] << " <directory path>\n\n"
<< "Given a directory of images, create a vector of\n"
<< "their names, read and display them. Filter out\n"
<< "non-images\n"
<< endl;
}
int main( int argc, const char** argv )
{
if(argc != 2) {
cerr << "\nIncorrect number of parameters: " << argc << ", should be 2\n" << endl;
help(argv);
return -1;
}
string folder = argv[1];
cout << "Reading in directory " << folder << endl;
vector<string> filenames;
int num_files = readFilenames(filenames, folder);
cout << "Number of files = " << num_files << endl;
cv::namedWindow( "image", 1 );
for(size_t i = 0; i < filenames.size(); ++i)
{
cout << folder + filenames[i] << " #" << i << endl;
cv::Mat src = cv::imread(folder + filenames[i]);
if(!src.data) { //Protect against no file
cerr << folder + filenames[i] << ", file #" << i << ", is not an image" << endl;
continue;
}
cv::imshow("image", src);
cv::waitKey(250); //For fun, wait 250ms, or a quarter of a second, but you can put in "0" for no wait or -1 to wait for keypresses
/* do whatever you want with your images here */
}
}
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.
How can I automatically open and read the content of a file within a given directory from a C++ application without knowing the file's name?
For example (a rough description of the program):
#include iomanip
#include dirent.h
#include fstream
#include iostream
#include stdlib.h
using namespace std;
int main()
{
DIR* dir;
struct dirent* entry;
dir=opendir("C:\\Users\\Toshiba\\Desktop\\links\\");
printf("Directory contents: ");
for(int i=0; i<3; i++)
{
entry=readdir(dir);
printf("%s\n",entry->d_name);
}
return 0;
}
This will print the name of the first file in that directory. My problem is how to read that particular file's content and save it in a .txt document. Can ifstream do that? (Sorry for my bad English.)
this should do it
#include <iostream>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
using namespace boost::filesystem;
using namespace std;
void show_files( const path & directory, bool recurse_into_subdirs = true )
{
if( exists( directory ) )
{
directory_iterator end ;
for( directory_iterator iter(directory) ; iter != end ; ++iter )
if ( is_directory( *iter ) )
{
cout << iter->native_directory_string() << " (directory)\n" ;
if( recurse_into_subdirs ) show_files(*iter) ;
}
else
cout << iter->native_file_string() << " (file)\n" ;
copyfiles(iter->native_file_string());
}
}
void copyfiles(string s)
{
ifstream inFile;
inFile.open(s);
if (!inFile.is_open())
{
cout << "Unable to open file";
exit(1); // terminate with error
}
//Display contents
string line = "";
//Getline to loop through all lines in file
while(getline(inFile,line))
{
cout<<line<<endl; // line buffers for every line
//here add your code to store this content in any file you want.
}
inFile.close();
}
int main()
{
show_files( "/usr/share/doc/bind9" ) ;
return 0;
}
If you're on Windows you can use the FindFirstFile in the Windows API. Here is a short example:
HANDLE myHandle;
WIN32_FIND_DATA findData;
myHandle = FindFirstFile("C:\\Users\\Toshiba\\Desktop\\links\\*", &findData);
do {
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
cout << "Directoryname is " << findData.cFileName << endl;
}
else{
cout << "Filename is " << findData.cFileName << endl;
}
} while (FindNextFile(myHandle, &findData));
Otherwise I'd go with ayushs answer, Boost works for unix systems as well