Is there a way to insert a string variable into CreateDirectory? I want it to create a directory in C: with the name the user has entered. When I do something like
CreateDirectory ("C:\\" << newname, NULL);
My compiler gives me the error "No match for operator<< in 'C:\ << newname'"
This is my code. The problem is in void newgame().
#include <iostream>
#include <fstream>
#include <string>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <mmsystem.h>
#include <conio.h>
using namespace std;
int a;
string newname;
string savepath;
struct game
{
string name;
int checkpoint;
int level;
};
void wait( time_t delay )
{
time_t timer0, timer1;
time( &timer0 );
do {
time( &timer1 );
} while (( timer1 - timer0 ) < delay );
}
void error()
{
cout << "\nError, bad input." << endl;
}
void options()
{
cout << "No options are currently implemented." << endl;
}
void load()
{
cout << "Load a Game:\n";
}
//This is where I'm talking about.
void newgame()
{
cout << "Name your Game:\n";
getline(cin,newname);
cin.get();
game g1;
g1.name=newname;
//I want it to create a dir in C: with the name the user has entered.
//How can I do it?
CreateDirectory ("C:\\" << newname, NULL);
}
//This isn't the whole piece of code, just most of it, I can post the rest if needed
CreateDirectory (("C:\\" + newname).c_str(), NULL);
You can join std::strings with operator+. Or, in your case, you can join a C string to an std::string using operator+, also. The result is an std::string. (Be careful though -- you cannot join two C strings together that way.)
I suspect, however, that CreateDirectory takes a C string, not a std::string, so you'll need to convert it with the .c_str() member.
To use stream insertion, you need to first create a stream:
std::ostringstream buffer;
buffer << "c:\\" << newname;
CreateDirectory(buffer.str().c_str());
Related
In my program I use an external function which generates output to me and I don't want it not to be generated by that function alone,
it's possible?
int main()
{
int a;
//I don't want the output of this function
a = function();
//now i want output
cout << "the result is : " << a;
}
Is it possible?
EDIT:
The function is in an external library.
Using only standard C++ where no dup-like functions exist, you could open a temporary std::FILE and std::swap with stdout.
#include <cerrno>
#include <cstring>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
// extern "C" int function(); // an assumption
// A helper class to temporarilly redirect the output to stdout to a file and to read
// the content of the file afterwards.
class BufferStdout {
public:
// the collector string is used for collecting the output to stdout
BufferStdout (std::string& collector) :
m_collector(collector),
fp(std::fopen("output.txt", "w"))
{
if(fp == nullptr) throw std::runtime_error(std::strerror(errno));
std::swap(stdout, fp); // swap stdout and the temp file
}
~BufferStdout () {
std::swap(stdout, fp); // swap back
std::fclose(fp);
// read the content of the temp file into m_collector
if(std::ifstream is("output.txt"); is) {
m_collector.append(std::istreambuf_iterator<char>(is),
std::istreambuf_iterator<char>{});
}
std::remove("output.txt"); // cleanup
}
private:
std::string& m_collector;
std::FILE* fp;
};
int main() {
std::string collector; // the string that will contain the output from function()
int a;
{
BufferStdout foo(collector);
a = function();
}
std::cout << "the result is : " << a << '\n';
std::cout << "Collected from function():\n";
std::cout << collector << '\n';
}
Yes it is generally possible but a bit complicated, a similar question is in Suppress output to cout from linked library
In addition to you can redirect stdout before invoking the shared library function and then redirect it again after the use of the shared library function in the however this is also a suboptimal solution. Best solution would be to adapt the shared library
// Cpp program to redirect cout to a file
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
fstream file;
file.open("cout.txt", ios::out);
string line;
// Backup streambuffers of cout
streambuf* stream_buffer_cout = cout.rdbuf();
streambuf* stream_buffer_cin = cin.rdbuf();
// Get the streambuffer of the file
streambuf* stream_buffer_file = file.rdbuf();
// Redirect cout to file
cout.rdbuf(stream_buffer_file);
cout << "This line written to file" << endl;
// Redirect cout back to screen
cout.rdbuf(stream_buffer_cout);
cout << "This line is written to screen" << endl;
file.close();
return 0;
}
Note: The above steps can be condensed into a single step
auto cout_buf = cout.rdbuf(file.rdbuf())
// sets couts streambuffer and returns the old
streambuffer back to cout_buf
source : https://www.geeksforgeeks.org/io-redirection-c/
use
fclose(stdout);
with this function you will suppress any printf inside your libraries.
Of course you can not print other stuff inside your software.
What am I missing here, this is my main program, I also have a makefile and everything works the error is somewhere in here.
#include <iostream>
#include <observer.h>
#include <fstream>
using namespace std;
int main(int argc, char* argv[]) {
std::fstream in;
int gettimeofday;
//CPUtypeandmodel
struct timeval now;
gettimeofday(&now, NULL);
cout << "Status report as of : " << ctime((time_t*)&now.tv_sec) << endl;
// Print machine name
in.open("/proc/sys/kernel/hostname");
string s;
in >> s;
cout << "Machine name: " << s << endl;
in.close();
return 1;
} //end main
When I try and make the file this happens
observer.cpp: In function ‘int main(int, char**)’:
observer.cpp:13:26: error: ‘gettimeofday’ cannot be used as a function
gettimeofday(&now, NULL);
^
<builtin>: recipe for target 'observer.o' failed
make: *** [observer.o] Error 1
You named a local int variable gettimeofday, which prevents you from calling the function gettimeofday() three lines later. Don't do that. Name the variable something else, or (given it seems unused) just get rid of it.
Your int gettimeofday; is shadowing the function with the same name. You don't even need that variable so remove it.
You need to include ctime and sys/time.h for the functions and classes you use.
You open the file /proc/sys/kernel/hostname for writing, which will fail unless you run the program as root.
The casting to time_t* is not necessary since &now.tv_sec is already a time_t*.
#include <sys/time.h>
#include <ctime>
#include <fstream>
#include <iostream>
#include <string>
int main() {
// CPUtypeandmodel
timeval now;
if(gettimeofday(&now, nullptr) == 0) // check for success
std::cout << "Status report as of : " << std::ctime(&now.tv_sec) << '\n';
// Print machine name
if(std::ifstream in("/proc/sys/kernel/hostname"); in) { // open for reading
std::string s;
if(in >> s) // check for success
std::cout << "Machine name: " << s << '\n';
} // no need to call in.close(), it'll close automatically here
return 1; // This usually signals failure. Return 0 instead.
} // end main
I am having some issues with my program, what I want to do is generate a md5 password which then save it to a text file and this part is not working for me, ("Expression invalid null pointer") any help would be greatly appreciated.
C++ Visual Studio 2015
main.cpp
#include <iostream>
#include <istream>
#include <string>
#include <sstream>
#include <fstream>
#include <iterator>
#include "s_encrypt.h"
#include "encrypt_copy.h"
using namespace std;
int main(int argc, char *argv[])
{
string password = "";
cout << "Please enter a password to be encrypted\n";
getline(cin, password);
cout << "MD5 Encryption of " << password << " " << "is this" << " " << md5(password);
cout << "Saving MD5 generated password to text file";
std::string p = md5(password);
CopyEncryptedPw(p);
return 0;
}
encrypt_copy.cpp
#include <istream>
#include <iostream>
#include <fstream>
#include <string>
#include "encrypt_copy.h"
using namespace std;
std::string CopyEncryptedPw(std::string pass)
{
fstream outfile;
outfile.open("C:\encrypted_pass.txt", ios::out);
outfile << pass;
return 0;
}
encrypt_copy.h
#pragma once
#ifndef ENCRYPT_H
#define ENCRYPT_H
std::string CopyEncryptedPw(std::string pass);
#endif
There are two issues with your code:
Issue 1:
outfile.open("C:\encrypted_pass.txt", ios::out);
If we assume that your OS is Windows, this should be:
outfile.open("C:\\encrypted_pass.txt", ios::out);
Also, the forward slash can be used for the standard stream functions:
outfile.open("C:/encrypted_pass.txt", ios::out);
Issue 2:
You're returning 0 for a function that is supposed to return a std::string.
std::string CopyEncryptedPw(std::string pass)
{
//...
return 0; // <-- This is bad
}
This code exhibits undefined behavior on return, since what will happen is that a 0 is assigned to the std::string return value, and assigning 0 to a std::string is undefined behavior.
Either return a string type (or a type that is convertible to a std::string), or return int:
int CopyEncryptedPw(std::string pass)
{
fstream outfile;
outfile.open("C:\\encrypted_pass.txt", ios::out);
outfile << pass;
return 0;
}
You could also have a void function that doesn't return anything, but you probably want an int return value for example, to return an error code (or OK indicator).
I want to create a small code in C++ with the same functionality as "tail-f": watch for new lines in a text file and show them in the standard output.
The idea is to have a thread that monitors the file
Is there an easy way to do it without opening and closing the file each time?
Have a look at inotify on Linux or kqueue on Mac OS.
Inotify is Linux kernel subsystem that allows you to subscribe for events on files and it will report to your application when the even happened on your file.
Just keep reading the file. If the read fails, do nothing. There's no need to repeatedly open and close it. However, you will find it much more efficient to use operating system specific features to monitor the file, should your OS provide them.
Same as in https://stackoverflow.com/a/7514051/44729 except that the code below uses getline instead of getc and doesn't skip new lines
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
static int last_position=0;
// read file untill new line
// save position
int find_new_text(ifstream &infile) {
infile.seekg(0,ios::end);
int filesize = infile.tellg();
// check if the new file started
if(filesize < last_position){
last_position=0;
}
// read file from last position untill new line is found
for(int n=last_position;n<filesize;n++) {
infile.seekg( last_position,ios::beg);
char test[256];
infile.getline(test, 256);
last_position = infile.tellg();
cout << "Char: " << test <<"Last position " << last_position<< endl;
// end of file
if(filesize == last_position){
return filesize;
}
}
return 0;
}
int main() {
for(;;) {
std::ifstream infile("filename");
int current_position = find_new_text(infile);
sleep(1);
}
}
I read this in one of Perl manuals, but it is easily translated into standard C, which, in turn, can be translated to istreams.
seek FILEHANDLE,POSITION,WHENCE
Sets FILEHANDLE's position, just like the "fseek" call of
"stdio".
<...>
A WHENCE of 1 ("SEEK_CUR") is useful for not moving the file
position:
seek(TEST,0,1);
This is also useful for applications emulating "tail -f". Once
you hit EOF on your read, and then sleep for a while, you might
have to stick in a seek() to reset things. The "seek" doesn't
change the current position, but it does clear the end-of-file
condition on the handle, so that the next "<FILE>" makes Perl
try again to read something. We hope.
As far as I remember, fseek is called iostream::seekg. So you should basically do the same: seek to the end of the file, then sleep and seek again with ios_base::cur flag to update end-of-file and read some more data.
Instead of sleeping, you may use inotify, as suggested in the other answer, to sleep (block while reading from an emulated file, actually) exactly until the file is updated/closed. But that's Linux-specific, and is not standard C++.
I needed to implement this too, I just wrote a quick hack in standard C++. The hack searches for the last 0x0A (linefeed character) in a file and outputs all data following that linefeed when the last linefeed value becomes a larger value. The code is here:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int find_last_linefeed(ifstream &infile) {
infile.seekg(0,ios::end);
int filesize = infile.tellg();
for(int n=1;n<filesize;n++) {
infile.seekg(filesize-n-1,ios::beg);
char c;
infile.get(c);
if(c == 0x0A) return infile.tellg();
}
}
int main() {
int last_position=-1;
for(;;) {
ifstream infile("testfile");
int position = find_last_linefeed(infile);
if(position > last_position) {
infile.seekg(position,ios::beg);
string in;
infile >> in;
cout << in << endl;
}
last_position=position;
sleep(1);
}
}
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <sys/stat.h>
#include <stdlib.h>
#define debug 0
class MyTail
{
private:
std::list<std::string> mLastNLine;
const int mNoOfLines;
std::ifstream mIn;
public:
explicit MyTail(int pNoOfLines):mNoOfLines(pNoOfLines) {}
const int getNoOfLines() {return mNoOfLines; }
void getLastNLines();
void printLastNLines();
void tailF(const char* filename);
};
void MyTail::getLastNLines()
{
if (debug) std::cout << "In: getLastNLines()" << std::endl;
mIn.seekg(-1,std::ios::end);
int pos=mIn.tellg();
int count = 1;
//Get file pointer to point to bottom up mNoOfLines.
for(int i=0;i<pos;i++)
{
if (mIn.get() == '\n')
if (count++ > mNoOfLines)
break;
mIn.seekg(-2,std::ios::cur);
}
//Start copying bottom mNoOfLines string into list to avoid I/O calls to print lines
std::string line;
while(getline(mIn,line)) {
int data_Size = mLastNLine.size();
if(data_Size >= mNoOfLines) {
mLastNLine.pop_front();
}
mLastNLine.push_back(line);
}
if (debug) std::cout << "Out: getLastNLines()" << std::endl;
}
void MyTail::printLastNLines()
{
for (std::list<std::string>::iterator i = mLastNLine.begin(); i != mLastNLine.end(); ++i)
std::cout << *i << std::endl;
}
void MyTail::tailF(const char* filename)
{
if (debug) std::cout << "In: TailF()" << std::endl;
int date = 0;
while (true) {
struct stat st;
stat (filename, &st);
int newdate = st.st_mtime;
if (newdate != date){
system("#cls||clear");
std::cout << "Print last " << getNoOfLines() << " Lines: \n";
mIn.open(filename);
date = newdate;
getLastNLines();
mIn.close();
printLastNLines();
}
}
if (debug) std::cout << "Out: TailF()" << std::endl;
}
int main(int argc, char **argv)
{
if(argc==1) {
std::cout << "No Extra Command Line Argument Passed Other Than Program Name\n";
return 0;
}
if(argc>=2) {
MyTail t1(10);
t1.tailF(argv[1]);
}
return 0;
}
I want to create a small code in C++ with the same functionality as "tail-f": watch for new lines in a text file and show them in the standard output.
The idea is to have a thread that monitors the file
Is there an easy way to do it without opening and closing the file each time?
Have a look at inotify on Linux or kqueue on Mac OS.
Inotify is Linux kernel subsystem that allows you to subscribe for events on files and it will report to your application when the even happened on your file.
Just keep reading the file. If the read fails, do nothing. There's no need to repeatedly open and close it. However, you will find it much more efficient to use operating system specific features to monitor the file, should your OS provide them.
Same as in https://stackoverflow.com/a/7514051/44729 except that the code below uses getline instead of getc and doesn't skip new lines
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
using namespace std;
static int last_position=0;
// read file untill new line
// save position
int find_new_text(ifstream &infile) {
infile.seekg(0,ios::end);
int filesize = infile.tellg();
// check if the new file started
if(filesize < last_position){
last_position=0;
}
// read file from last position untill new line is found
for(int n=last_position;n<filesize;n++) {
infile.seekg( last_position,ios::beg);
char test[256];
infile.getline(test, 256);
last_position = infile.tellg();
cout << "Char: " << test <<"Last position " << last_position<< endl;
// end of file
if(filesize == last_position){
return filesize;
}
}
return 0;
}
int main() {
for(;;) {
std::ifstream infile("filename");
int current_position = find_new_text(infile);
sleep(1);
}
}
I read this in one of Perl manuals, but it is easily translated into standard C, which, in turn, can be translated to istreams.
seek FILEHANDLE,POSITION,WHENCE
Sets FILEHANDLE's position, just like the "fseek" call of
"stdio".
<...>
A WHENCE of 1 ("SEEK_CUR") is useful for not moving the file
position:
seek(TEST,0,1);
This is also useful for applications emulating "tail -f". Once
you hit EOF on your read, and then sleep for a while, you might
have to stick in a seek() to reset things. The "seek" doesn't
change the current position, but it does clear the end-of-file
condition on the handle, so that the next "<FILE>" makes Perl
try again to read something. We hope.
As far as I remember, fseek is called iostream::seekg. So you should basically do the same: seek to the end of the file, then sleep and seek again with ios_base::cur flag to update end-of-file and read some more data.
Instead of sleeping, you may use inotify, as suggested in the other answer, to sleep (block while reading from an emulated file, actually) exactly until the file is updated/closed. But that's Linux-specific, and is not standard C++.
I needed to implement this too, I just wrote a quick hack in standard C++. The hack searches for the last 0x0A (linefeed character) in a file and outputs all data following that linefeed when the last linefeed value becomes a larger value. The code is here:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int find_last_linefeed(ifstream &infile) {
infile.seekg(0,ios::end);
int filesize = infile.tellg();
for(int n=1;n<filesize;n++) {
infile.seekg(filesize-n-1,ios::beg);
char c;
infile.get(c);
if(c == 0x0A) return infile.tellg();
}
}
int main() {
int last_position=-1;
for(;;) {
ifstream infile("testfile");
int position = find_last_linefeed(infile);
if(position > last_position) {
infile.seekg(position,ios::beg);
string in;
infile >> in;
cout << in << endl;
}
last_position=position;
sleep(1);
}
}
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <sys/stat.h>
#include <stdlib.h>
#define debug 0
class MyTail
{
private:
std::list<std::string> mLastNLine;
const int mNoOfLines;
std::ifstream mIn;
public:
explicit MyTail(int pNoOfLines):mNoOfLines(pNoOfLines) {}
const int getNoOfLines() {return mNoOfLines; }
void getLastNLines();
void printLastNLines();
void tailF(const char* filename);
};
void MyTail::getLastNLines()
{
if (debug) std::cout << "In: getLastNLines()" << std::endl;
mIn.seekg(-1,std::ios::end);
int pos=mIn.tellg();
int count = 1;
//Get file pointer to point to bottom up mNoOfLines.
for(int i=0;i<pos;i++)
{
if (mIn.get() == '\n')
if (count++ > mNoOfLines)
break;
mIn.seekg(-2,std::ios::cur);
}
//Start copying bottom mNoOfLines string into list to avoid I/O calls to print lines
std::string line;
while(getline(mIn,line)) {
int data_Size = mLastNLine.size();
if(data_Size >= mNoOfLines) {
mLastNLine.pop_front();
}
mLastNLine.push_back(line);
}
if (debug) std::cout << "Out: getLastNLines()" << std::endl;
}
void MyTail::printLastNLines()
{
for (std::list<std::string>::iterator i = mLastNLine.begin(); i != mLastNLine.end(); ++i)
std::cout << *i << std::endl;
}
void MyTail::tailF(const char* filename)
{
if (debug) std::cout << "In: TailF()" << std::endl;
int date = 0;
while (true) {
struct stat st;
stat (filename, &st);
int newdate = st.st_mtime;
if (newdate != date){
system("#cls||clear");
std::cout << "Print last " << getNoOfLines() << " Lines: \n";
mIn.open(filename);
date = newdate;
getLastNLines();
mIn.close();
printLastNLines();
}
}
if (debug) std::cout << "Out: TailF()" << std::endl;
}
int main(int argc, char **argv)
{
if(argc==1) {
std::cout << "No Extra Command Line Argument Passed Other Than Program Name\n";
return 0;
}
if(argc>=2) {
MyTail t1(10);
t1.tailF(argv[1]);
}
return 0;
}