fstream fails to write/open files on raspberry pi - c++

I am trying to run a cpp program on raspberry pi 3 b+ (from 'pi' user) but when I try to open a file with 'fstream' library it doesn't work.
I am using the following code (from main):
std::ios::sync_with_stdio(false);
std::string path = "/NbData";
std::ofstream nbData(path);
if (!nbData) {
std::cout << "Error during process...";
return 0;
}
nbData.seekp(std::ios::beg);
The program always fails there and stops because no file is created (I don't get a fatal error but the test fails and it outputs 'Error during process' which means no file was created).
I am compiling with the following command (there are no issues when I compile):
g++ -std=c++0x nbFinder.cpp -o nbFinder
I have already tried my program on Xcode and everything worked perfectly...

The problem is your path. You must put the file, you are using just the path and if the path do not exist will throw an error. In your case you just using std::string path = "/NbData";, that is you path not your file.
To be able to open your file you need make sure your path exist. Try use the code bellow, he will check if the path exist case not will create and then try to open your file.
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
int main() {
std::ios::sync_with_stdio(false);
std::string path = "./test_dir/";
std::string file = "test.txt";
// Will check if thie file exist, if not will creat
struct stat info;
if (stat(path.c_str(), &info) != 0) {
std::cout << "cannot access " << path << std::endl;
system(("mkdir " + path).c_str());
} else if(info.st_mode & S_IFDIR) {
std::cout << "is a directory" << path << std::endl;
} else {
std::cout << "is no directory" << path << std::endl;
system(("mkdir " + path).c_str());
}
std::ofstream nbData(path + file);
if (!nbData) {
std::cout << "Error during process...";
return 0;
}
nbData.seekp(std::ios::beg);
return 0;
}

Related

How to grant access to hosts.txt file using C++ 11 on MacOS

I am attempting to write a program that can append text to a given host file on MacOS, but due to permission issues I am not allowed to do so.
Here's my code:
#include <iostream>
#include <fstream>
int main(int argc, const char * argv[]) {
std::ofstream myfile;
myfile.open("/private/etc/hosts.txt", std::ios::app);
if(!myfile.is_open()){
std::cout << "Host file could not be opened or located" << std::endl;
} else {
myfile << "data to be appended" << std::endl;
std::cout << "Host file has been modified" << std::endl;
myfile.close();
}
return 0;
}
I created a public folder with a mock of the hosts.txt file in the same root directory and it worked so I'm positive it is a permission error but I am BRAND new to working with files in C++ and have no idea how to proceed or if what I'm doing is even possible.
Thanks

Reading a file from an exported folder

I have file (let's call it "file.txt") which is in a folder /folder/where/the/file/is.
And this folder has been exported to $FOLDER, such as if I do :
echo $FOLDER, I got : folder/where/the/file/is
Now, I want to test if the file exists or not.
So, I tried
ifstream ifile(Name_finput);
if(!ifile.good()){
cout << "File doesn't exist !" << endl;
return;
}
This works if Name_finput = "/folder/where/the/file/is/file.txt", but not if Name_finput=$FOLDER/file.txt
Is there a way for it to work by keeping the form $FOLDER/file.txt ?
It seems that the compiler doesn't interpret $FOLDER as /folder/where/the/file/is.
$FOLDER is not valid C++ code. In order to access the environment variables, you need to use std::getenv(). Here's how your code should look:
#include <iostream>
#include <cstdlib>
#include <fstream>
int main() {
std::ifstream ifile;
if (const char* e = std::getenv("FOLDER")) {
ifile.open(std::string(e) + std::string("/file.txt"));
if (!ifile.is_open()) {
std::cout << "File doesn't exist !" << std::endl;
} else {
// Do-stuff with the file
}
}
return 0;
}

C++ Trouble Reading a Text File

I'm trying to read a text file but nothing is coming out. I feel like maybe It's not linking correctly in my Visual Studio Resources folder but if I double click it - it opens fine in visual studio and it doesn't run into any problems if I test to see if it opens or if it is good. The program compiles fine right now but there's not output. Nothing prints to my command prompt. Any suggestions?
Code
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
int main()
{
char str[100];
ifstream test;
test.open("test.txt");
while(test.getline(str, 100, '#'))
{
cout << str << endl;
}
test.close();
return 0;
}
Text File
This is a test Textfile#Read more lines here#and here
You try to open file by name without path, this means the file shall be in current working directory of your program.
The problem is with current directory when you run your program from VS IDE. VS by default sets current working directory for runnning program to project directory $(ProjectDir). But your test file resides in resources directory. So open() function could not find it and getline() immediately fails.
Solution is simple - copy your test file to project directory. Or copy it to target directory (where your program .exe file is created, typically $(ProjectDir)\Debug or $(ProjectDir)\Release) and change working directory setting in VS IDE: Project->Properties->Debugging->Working Directory, set to $(TargetDir). In this case it will work both from IDE and command line/Windows Explorer.
Another possible solution - set correct path to file in your open() call. For testing/education purposes you could hardcode it, but actually this is not good style of software development.
Not sure if this will help but I wanted to simply open a text file for output and then read it back in. Visual Studio (2012) seems to make this difficult. My solution is demonstrated below:
#include <iostream>
#include <fstream>
using namespace std;
string getFilePath(const string& fileName) {
string path = __FILE__; //gets source code path, include file name
path = path.substr(0, 1 + path.find_last_of('\\')); //removes file name
path += fileName; //adds input file to path
path = "\\" + path;
return path;
}
void writeFile(const string& path) {
ofstream os{ path };
if (!os) cout << "file create error" << endl;
for (int i = 0; i < 15; ++i) {
os << i << endl;
}
os.close();
}
void readFile(const string& path) {
ifstream is{ path };
if (!is) cout << "file open error" << endl;
int val = -1;
while (is >> val) {
cout << val << endl;
}
is.close();
}
int main(int argc, char* argv[]) {
string path = getFilePath("file.txt");
cout << "Writing file..." << endl;
writeFile(path);
cout << "Reading file..." << endl;
readFile(path);
return 0;
}

C++: Error with Boost Filesystem copy_file

I'm running into some trouble with the copy_file function. My program is very simple, I'm just attempting to copy a text file from one spot to another.
The following code brings up a "Debug Error!" because abort() was called.
int main()
{
path src_path = "C:\\src.txt";
path dst_path = "C:\\dst.txt";
cout << "src exists = " << exists( src_path ) << endl; // Prints True
boost::filesystem::copy_file( src_path, dst_path );
return 0;
}
If I look at some other examples of code on Stackoverflow I cannot notice what I'm doing wrong. I feel like I'm missing something obvious here.
I have Boost v1.47 installed and I'm using Visual C++ 2010.
I'm guessing that the target file exists.
The docs:
template <class Path1, class Path2> void copy_file(const Path1& from_fp, const Path2& to_fp);
Requires: Path1::external_string_type and Path2::external_string_type are the same type.
Effects: The contents and attributes of the file from_fp resolves to are copied to the file to_fp resolves to.
Throws: basic_filesystem_error<Path> if from_fp.empty() || to_fp.empty() || !exists(from_fp) || !is_regular_file(from_fp) || exists(to_fp)
A simple test like so:
#include <iostream>
#include <boost/filesystem.hpp>
int main()
{
using namespace boost::filesystem;
path src_path = "test.in";
path dst_path = "test.out";
std::cout << "src exists = " << std::boolalpha << exists( src_path ) << std::endl; // Prints true
try
{
boost::filesystem::copy_file( src_path, dst_path );
} catch (const boost::filesystem::filesystem_error& e)
{
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
Prints:
src exists = true
Error: boost::filesystem::copy_file: File exists: "test.in", "test.out"
on the second run :)
I think if you are using boost::filesystem2 it should be
boost::filesystem2::copy(src_path,dest_path);
copy_file should have been deprecated.

C++ - stat(), access() not working under gnu gcc

I've got a pretty basic console program here, to determine if a folder or file exists or not using stat:
#include <iostream>
#include <sys/stat.h>
using namespace std;
int main() {
char path[] = "myfolder/";
struct stat status;
if(stat(path,&status)==0) { cout << "Folder found." << endl; }
else { cout << "Can't find folder." << endl; } //Doesn't exist
cin.get();
return 0;
}
I have also tried the access version:
#include <iostream>
#include <io.h>
using namespace std;
int main() {
char path[] = "myfolder/";
if(access(path,0)==0) { cout << "Folder found." << endl; }
else { cout << "Can't find folder." << endl; } //Doesn't exist
cin.get();
return 0;
}
Neither of them find my folder (which is right there in the same directory as the program). These worked on my last compiler (the default one with DevCpp). I switched to CodeBlocks and am compiling with Gnu GCC now, if that helps. I'm sure it's a quick fix - can someone help out?
(Obviously I'm a noob at this so if you need any other information I've left out please let me know).
UPDATE
The problem was with the base directory. The updated, working program is as follows:
#include <iostream>
#include <sys/stat.h>
using namespace std;
int main() {
cout << "Current directory: " << system("cd") << endl;
char path[] = "./bin/Release/myfolder";
struct stat status;
if(stat(path,&status)==0) { cout << "Directory found." << endl; }
else { cout << "Can't find directory." << endl; } //Doesn't exist
cin.get();
return 0;
}
ANOTHER UPDATE
Turns out that a trailing backslash on the path is big trouble.
Right before your stat call, insert the code:
system("pwd"); // for UNIXy systems
system("cd"); // for Windowsy systems
(or equivalent) to check your current directory. I think you'll find it's not what you think.
Alternatively, run the executable from the command line where you know what directory you're in. IDEs will frequently run your executable from a directory you may not expect.
Or, use the full path name so that it doesn't matter which directory you're in.
For what it's worth, your first code segment works perfectly (gcc under Ubuntu 10):
pax$ ls my*
ls: cannot access my*: No such file or directory
pax$ ./qq
Cannot find folder.
pax$ mkdir myfolder
pax$ ll -d my*
drwxr-xr-x 2 pax pax 4096 2010-12-14 09:33 myfolder/
pax$ ./qq
Folder found.
Are you sure that the current directory of your running program is what you expect it to be? Try changing path to an absolute pathname to see if that helps.
Check your PWD when you running your program. This problem is not caused by compiler. You DevCpp may set a working directory for your program automatically.
You can find out why stat() failed (which is a C function, not C++, by the way), by checking errno:
#include <cerrno>
...
if (stat(path,&status) != 0)
{
std::cout << "stat() failed:" << std::strerror(errno) << endl;
}