How to read Unix formatted EOL perl files in a MFC application using CStdioFile class? when I am reading the file using GetPostion() and ReadLine() methods it is going into infinite loop. any help pls...
You should use CStdioFile like this:
CStdioFile f;
CString sData;
CString sLine;
if( f.Open( _T("C:\MyFiles\MyFile.txt"), CFile::modeRead | CFile::typeText ))
{
while (f.ReadString(sLine))
{
sData += sLine;
}
f.Close();
}
Related
I'm looking for the best possible approach to incorporate a batch file to send arguments to the MFC application rather than relying on the GUI interface. Does anyone know the best method to go about doing this?
I use the following code in my InitInstance method of my app class:
LPWSTR *szArglist = nullptr;
int iNumArgs = 0;
szArglist = CommandLineToArgvW(GetCommandLine(), &iNumArgs);
if (iNumArgs > 0 && szArglist != nullptr)
{
for (int iArg = 0; iArg < iNumArgs; iArg++)
{
CString strArg(szArglist[iArg]);
int iDelim = strArg.Find(_T("="));
if (iDelim != -1)
{
CString strParamName = strArg.Left(iDelim);
CString strParamValue = strArg.Mid(iDelim + 1);
if (strParamName.CollateNoCase(_T("/lang")) == 0)
{
m_strPathLanguageResourceOverride.Format(_T("%sMeetSchedAssist%s.dll"),
(LPCTSTR)GetProgramPath(), (LPCTSTR)strParamValue.MakeUpper());
if (!PathFileExists(m_strPathLanguageResourceOverride))
m_strPathLanguageResourceOverride = _T("");
}
}
}
// Free memory allocated for CommandLineToArgvW arguments.
LocalFree(szArglist);
}
As you can see, I use the CommandLineToArgvW method to extract and process the command line arguments.
A GUI program can receive command line arguments just like a command line program can.
Your Application class (CWinApp, if memory serves) contains a member named m_lpCmdLine that contains the command line arguments (if any) in a CString.
If you also want to deal with shell parameters, you'll probably also want to look at WinApp::ParseCommandLine and CCommandLineInfo (note, if you're dealing with a Wizard-generated program, chances are that WinApp::ParseCommandLine is already being called by default).
How can I read the content of boost::interprocess::file_handle_t?
We are currently prototyping with code found at scoped_lock doesn't work on file?. This demonstrates how to write but we would also like to read from the file. How can this be accomplished? Done the normal google search and looked at boost docs and header files without any luck. Appreciate any input.
#include "boost/format.hpp"
#include "boost/interprocess/detail/os_file_functions.hpp"
namespace ip = boost::interprocess;
namespace ipc = boost::interprocess::detail;
void fileLocking_withHandle()
{
static const string filename = "fileLocking_withHandle.txt";
// Get file handle
boost::interprocess::file_handle_t pFile = ipc::create_or_open_file(filename.c_str(), ip::read_write);
if ((pFile == 0 || pFile == ipc::invalid_file()))
{
throw runtime_error(boost::str(boost::format("File Writer fail to open output file: %1%") % filename).c_str());
}
// Lock file
ipc::acquire_file_lock(pFile);
// Move writing pointer to the end of the file
ipc::set_file_pointer(pFile, 0, ip::file_end);
// Write in file
ipc::write_file(pFile, (const void*)("bla"), 3);
// Unlock file
ipc::release_file_lock(pFile);
// Close file
ipc::close_file(pFile);
}
We are developing on Windows and Linux.
To solve the issue we used platform specific method.
So for Windows platform we used ReadFile(..) [#include "Windows"] and for Linux we used read(..) [#include
I would like to write my output to a file if a file name is avaliable or on the screen (stdout) otherwise. So I've read posts on this forum and found a code, which below I wrapped into a method:
std::shared_ptr<std::ostream> out_stream(const std::string & fname) {
std::streambuf * buf;
std::ofstream of;
if (fname.length() > 0) {
of.open(fname);
buf = of.rdbuf();
} else
buf = std::cout.rdbuf();
std::shared_ptr<std::ostream> p(new std::ostream(buf));
return p;
}
The code works perfectly when used in-place. Unfortunately it behaves oddly when wrapped into a separate method (as given above). Is it because the the objects defined within the method (of, buff) are destroyed once the call is finished?
I am using this part of code in several places and it really should be extracted as a separate non-repeating fragment: a method or a class. How can I achieve this?
You're correct that the problems you're having come from the destruction of of. Wouldn't something like this (untested) work?
std::shared_ptr<std::ostream>
out_stream(const std::string &fname) {
if (fname.length() > 0)
std::shared_ptr<std::ostream> p(new std::ofstream(fname));
else
std::shared_ptr<std::ostream> p(new std::ostream(std::cout.rdbuf()));
}
Using Perl, how do I capture a single character from STDIN without needing the user to hit enter (similar to C's getch() function)?
Perl has a getc() function, but according to the perlfunc:
However, it cannot be used by itself to fetch
single characters without waiting for
the user to hit enter.
The perlfunc docs do provides a way to read a single character using getc() but it requires manipulating the terminal settings using stty. The script I'm writing needs to work on Windows (without cygwin, msys, etc.) - so that's not an option.
From perlfaq5's answer to How can I read a single character from a file? From the keyboard?
You can use the builtin getc() function for most filehandles, but it won't (easily) work on a terminal device. For STDIN, either use the Term::ReadKey module from CPAN or use the sample code in getc in perlfunc.
If your system supports the portable operating system programming interface (POSIX), you can use the following code, which you'll note turns off echo processing as well.
#!/usr/bin/perl -w
use strict;
$| = 1;
for (1..4) {
my $got;
print "gimme: ";
$got = getone();
print "--> $got\n";
}
exit;
BEGIN {
use POSIX qw(:termios_h);
my ($term, $oterm, $echo, $noecho, $fd_stdin);
$fd_stdin = fileno(STDIN);
$term = POSIX::Termios->new();
$term->getattr($fd_stdin);
$oterm = $term->getlflag();
$echo = ECHO | ECHOK | ICANON;
$noecho = $oterm & ~$echo;
sub cbreak {
$term->setlflag($noecho);
$term->setcc(VTIME, 1);
$term->setattr($fd_stdin, TCSANOW);
}
sub cooked {
$term->setlflag($oterm);
$term->setcc(VTIME, 0);
$term->setattr($fd_stdin, TCSANOW);
}
sub getone {
my $key = '';
cbreak();
sysread(STDIN, $key, 1);
cooked();
return $key;
}
}
END { cooked() }
The Term::ReadKey module from CPAN may be easier to use. Recent versions include also support for non-portable systems as well.
use Term::ReadKey;
open(TTY, "</dev/tty");
print "Gimme a char: ";
ReadMode "raw";
$key = ReadKey 0, *TTY;
ReadMode "normal";
printf "\nYou said %s, char number %03d\n",
$key, ord $key;
You want this module: Term::ReadKey.
Description:
Obtain output from an executable
Note:
Will not compile, due to fgets() declaration
Question:
What is the best alternative to fgets, as fgets requires char *?
Is there a better alternative?
Illustration:
void Q_analysis (const char *data)
{
string buffer;
size_t found;
found = buffer.find_first_of (*data);
FILE *condorData = _popen ("condor_q", "r");
while (fgets (buffer.c_str(), buffer.max_size(), condorData) != NULL)
{
if (found == string::npos)
{
Sleep(2000);
} else {
break;
}
}
return;
}
You should be using the string.getline function for strings
cppreference
however in your case, you should be using a char[] to read into.
eg
string s;
char buffer[ 4096 ];
fgets(buffer, sizeof( buffer ), condorData);
s.assign( buffer, strlen( buffer ));
or your code:
void Q_analysis( const char *data )
{
char buffer[ 4096 ];
FILE *condorData = _popen ("condor_q", "r");
while( fgets( buffer, sizeof( buffer ), condorData ) != NULL )
{
if( strstr( buffer, data ) == NULL )
{
Sleep(2000);
}
else
{
break;
}
}
}
Instead of declaring you buffer as a string declare it as something like:
char buffer[MY_MAX_SIZE]
call fgets with that, and then build the string from the buffer if you need in that form instead of going the other way.
The reason what you're doing doesn't work is that you're getting a copy of the buffer contents as a c-style string, not a pointer into the gut of the buffer. It is, by design, read only.
-- MarkusQ
You're right that you can't read directly into a std::string because its c_str and data methods both return const pointers. You could read into a std::vector<char> instead.
You could also use the getline function. But it requires an iostream object, not a C FILE pointer. You can get from one to the other, though, in a vendor-specific way. See "A Handy Guide To Handling Handles" for a diagram and some suggestions on how to get from one file type to another. Call fileno on your FILE* to get a numeric file descriptor, and then use fstream::attach to associate it with an fstream object. Then you can use getline.
Try the boost library - I believe it has a function to create an fstream from a FILE*
or you could use fileno() to get a standard C file handle from the FILE, then use fstream::attach to attach a stream to that file. From there you can use getline(), etc. Something like this:
FILE *condorData = _popen ("condor_q", "r");
std::ifstream &stream = new std::ifstream();
stream.attach(_fileno(condorData));
I haven't tested it all too well, but the below appears to do the job:
//! read a line of text from a FILE* to a std::string, returns false on 'no data'
bool stringfgets(FILE* fp, std::string& line)
{
char buffer[1024];
line.clear();
do {
if(!fgets(buffer, sizeof(buffer), fp))
return !line.empty();
line.append(buffer);
} while(!strchr(buffer, '\n'));
return true;
}
Be aware however that this will happily read a 100G line of text, so care must be taken that this is not a DoS-vector from untrusted source files or sockets.