Roman to decimal conversion - c++

What do you think about this code? Is it the best way? Any improvement?
Roman.h
#ifndef ROMAN_H
#define ROMAN_H
#include <string>
#include <map>
typedef unsigned long int UL_I;
typedef std::map< std::string, UL_I, std::less< std::string > > Map;
class Roman_Number
{
public:
//Constructor
Roman_Number( std::string );
void Convert_to_decimal();
UL_I get_Decimal() const;
std::string get_Roman() const;
private:
std::string s_roman_number;
UL_I d_number;
Map pairs;
Map pairs_substracting;
//Utilitaries functions
void _validate_();
void _initilize_pairs_()
{
pairs.insert( Map::value_type( "I", 1 ) );
pairs_substracting.insert( Map::value_type ( "IV", 4 ) );
pairs.insert( Map::value_type( "V", 5 ) );
pairs_substracting.insert( Map::value_type( "IX", 9 ) );
pairs.insert( Map::value_type( "X", 10 ) );
pairs_substracting.insert( Map::value_type( "XL", 40 ) );
pairs.insert( Map::value_type( "L", 50 ) );
pairs_substracting.insert( Map::value_type( "XC", 90 ) );
pairs.insert( Map::value_type( "C", 100 ) );
pairs_substracting.insert( Map::value_type( "CD", 400 ) );
pairs.insert( Map::value_type( "D", 500 ) );
pairs_substracting.insert( Map::value_type( "CM", 900 ) );
}
UL_I _recursive_convert( std::string );
};
#endif
Roman.cpp
#include <iostream>
#include "Roman.h"
void Roman_Number::_validate_()
{
std::cout << "Validating" << std::endl;
}
Roman_Number::Roman_Number(std::string r_number )
{
_initilize_pairs_();
s_roman_number = r_number;
d_number = 0;
}
void Roman_Number::Convert_to_decimal()
{
std::string s_aux = s_roman_number;
d_number = _recursive_convert( s_aux );
}
UL_I Roman_Number::_recursive_convert( std::string new_roman )
{
if( new_roman == "" )
return 0;
if( pairs_substracting.find( new_roman.substr( 0 , 2 ) ) != pairs_substracting.end() )
return pairs_substracting[new_roman.substr( 0, 2 )] +
_recursive_convert( new_roman.erase( 0, 2) );
else
return pairs[new_roman.substr( 0, 1 )] + _recursive_convert( new_roman.erase( 0, 1 ) );
}
UL_I Roman_Number::get_Decimal() const
{
return d_number;
}
std::string Roman_Number::get_Roman() const
{
return s_roman_number;
}
main.cpp
#include <iostream>
#include "Roman.h"
int main() {
Roman_Number R_N( "XIL" );
R_N.Convert_to_decimal();
std::cout << R_N.get_Decimal();
return 0;
}

How about this? http://codepad.org/mJ05BldC
#include <stdio.h>
int main( void ) {
const char* s = "MCDXLIV";
int x = 0; // result
int j,m=0; // max used digit
const char* p=s, *q; while(*p) ++p;
for( --p; p>=s; p-- ) for( q="IVXLCDM",j=0; *q; q++,j++ ) if( *p==*q )
x += ((j>=m)?m=j,1:-1) * (1+j%4/2*9) * (1+j/4*99) * (1+j%2*4);
printf( "s=%s x=%i\n", s, x );
}

Given
public static final String romanNums = "IVXLCDM";
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
String input = console.nextLine();
int arabInt = 0;
for (int i = 0; i < romanNums.length(); i++) {
for (int j = 0; j < input.length(); j++) {
if (input.substring(j, j + 1).equals(romanNums.substring(i, i + 1))) {
arabInt += convertRomToNum(i);
if (j > 0 && romanNums.indexOf(input.substring(j, j + 1)) > romanNums.indexOf(input.substring(j - 1, j))) {
arabInt -= 2 * convertRomToNum(romanNums.indexOf(input.substring(j - 1, j)));
}
}
}
// AFTER OBSERVING PATTERN: 1, 5, 10, 50, 100, 500, 1000; AND ASSOCIATING INDEXES
// OF EACH ROMAN LETTER WITH CORRESPONDING NUMBER IN SEQUENCE ABOVE
public static int convertRomToNum(int i) {
int numBehindLetter = (int) (Math.pow(2, Math.floor(i / 2)) * Math.pow(5, Math.ceil(i / 2.)));
return numBehindLetter;
}
1 = 5^0 * 2^0; 5 = 5^1*2^0; 10 = 5^1*2^0; 50 = 5^2*2^1; 100 = 5^2*2^2; 500 = 5^3*2^2; 1000 = 5^3*2^3 and so on. This is why I have used 'floor' and 'ceil' functions.

Somewhere between convoluted and readable ...
int convRomanToInt(string roman) {
char[] symbol = { 'M', 'D', 'C', 'L', 'X','V','I' };
int[] weight = { 1000, 500, 100, 50, 10, 5 , 1 };
int res = 0, rom = 0, num = 0;
while (rom < roman.Length){
if (roman[rom] == symbol[num]){
res += weight[num];
rom++;
} else if (rom < roman.Length-1 && roman[rom+1] == symbol[num]){
res -= weight[(num&~1)+2];
rom++;
} else {
num++;
}
}
return res;
}

Related

Templates and Array of structs that contain pointer to method in class

I am trying to create a class that defines an array of command structs, each of which has two CHAR variables, one CHAR*, one INT and a pointer to a void function that accepts two CHAR arguments. There will be multiple instances of this array, each in a different class. I feel like I am close, but missing something critical. The Arduino GNU compiler seems to agree that I am missing something. Here's the code (with modifications as per Bo R);
<<<<<<<<<< Commands.h >>>>>>>>>>>>>>>>>
#pragma once
//template <class T>
class Commands {
public:
typedef void ( Commands::*FunctionPointer )( char, char );
struct command {
char sel;
char act;
char const *desc;
FunctionPointer funcPtr;
};
command myCommands [2] = {
command { 'a','?',"FOO", &Commands::foo },
command { 'b','x',"BAR", &Commands::bar },
};
int cmdSize = sizeof ( myCommands ) / sizeof ( myCommands [0] );
void foo ( char sel, char act ) {
show ( { sel }, { act } );
}
void bar ( char sel, char act ) {
show ( { sel }, { act } );
}
void show ( char sel, char act ) {
Serial.print ( "SEL = " );
Serial.print ( sel );
Serial.print ( " ACT = " );
Serial.println ( act );
}
void execute ( char sel, char act ) {
for (int i = 0; i < cmdSize; i++) {
if (myCommands [i].sel == sel && myCommands [i].act == act) {
Serial.println ( myCommands [i].desc );
( this->*myCommands [i].funcPtr )( sel, act );
return;
}
}
Serial.print ( F ( "Unknown SEL/ACT Pair:" ) );
Serial.print ( sel );
Serial.print ( '/' );
Serial.println ( act );
}
};
<<<<<<<<<< StructArray.ino >>>>>>>>>>>>>>>>>
#include "Commands.h"
Commands cmd;
void setup() {
Serial.begin ( 115200 );
Serial.println ( "EXECUTING:" );
cmd.execute ( 'a', '?' );
cmd.execute ( 'b', '?' );
cmd.execute ( 'b', 'x' );
Serial.println ( "DONE" );
}
void loop(){}
If I refactor Commands into Template.h and Foo.h (as below), I get four compile errors that I don't understand how to fix:
Severity Code Description File Line
Error error: invalid use of template-name 'Template' without an argument list D:\Documents\Arduino\StructArray\Foo.h 6
Error error: 'myCommands' was not declared in this scope D:\Documents\Arduino\StructArray\Foo.h 11
Error error: 'myCommands' was not declared in this scope D:\Documents\Arduino\StructArray\Foo.h 11
Error error: invalid use of template-name 'Foo' without an argument list D:\Documents\Arduino\StructArray\StructArray.ino 7
Here is the code for Template.h:
#pragma once
template <class T>
class Template {
public:
typedef void ( T::*FunctionPointer )( char, char );
struct command {
char sel;
char act;
char const *desc;
FunctionPointer funcPtr;
};
void show ( char sel, char act ) {
Serial.print ( "SEL = " );
Serial.print ( sel );
Serial.print ( " ACT = " );
Serial.println ( act );
}
void execute ( char sel, char act, int cmdSize ) {
for (int i = 0; i < cmdSize; i++) {
if (T::myCommands[i].sel == sel && T::myCommands [i].act == act) {
Serial.println ( T::myCommands [i].desc );
( this->*T::myCommands [i].funcPtr )( sel, act );
return;
}
}
Serial.print ( F ( "Unknown SEL/ACT Pair:" ) );
Serial.print ( sel );
Serial.print ( '/' );
Serial.println ( act );
}
};
And Foo.h:
#pragma once
#include "Template.h"
template<class T>
class Foo {
public:
Template::command myCommands [2] = {
command { 'a','?',"FOO-A", &Foo::foo },
command { 'b','x',"FOO-B", &Foo::bar },
};
int cmdSize = sizeof ( myCommands ) / sizeof ( myCommands [0] );
void foo ( char sel, char act ) {
show ( { sel }, { act } );
}
void bar ( char sel, char act ) {
show ( { sel }, { act } );
}
};
If I start you out on the non-templated version, you will see that you need to make some changes.
class Commands {
public:
typedef void ( Commands::*FunctionPointer )( char, char );
struct command {
char sel;
char act;
char const *desc;
FunctionPointer funcPtr;
};
command myCommands [2] = {
{ 'a','?',"FOO", &Commands::foo },
{ 'b','x',"BAR", &Commands::bar }
};
int cmdSize = sizeof ( this->myCommands ) / sizeof ( this->myCommands [0] );
void foo ( char sel, char act ) {
char buf[2] = {sel};
Serial.println ( buf );
}
void bar ( char sel, char act ) {
char buf[2] = { sel };
Serial.println ( buf );
}
void execute ( char sel, char act ) {
for (int i = 0; i < cmdSize; i++) {
if (myCommands [i].sel == sel && myCommands [i].act == act) {
Serial.println ( myCommands [i].desc );
(this->*myCommands [i].funcPtr)( sel, act );
}
}
}
};
Once that is solved you can attack the templating (which I didn't see the purpose right now in this example since the foo and bar were part of the template class.)

C++ MFC How to prevent duplicate values in each Ch?

I have the following code:
And I would like to select one Ch without the number which has been selected in the other Ch.
For example, in Ch5, "1","2","3","37" can not be selected.
BOOL CMaintenanceHeadDispenserDlg::OnInitDialog()
{
CMaintenanceChildDlg::OnInitDialog();
CRect rc(0, 0, 0, 0);
m_edtDist.Create( NULL, NULL, WS_CHILD|WS_VISIBLE|WS_DISABLED, rc, this, IDC_EDT_MT_HEAD_DISPENSER_DIST );
m_edtDist.SetInputMode( 1 );
m_edtDist.SetInputRange( 999.999, 0.0 );
m_edtDist.EnableRightInputMode( TRUE, 2 );
m_edtOutput.Create(NULL, WS_CHILD|WS_VISIBLE|WS_DISABLED, rc, this, IDC_EDT_MT_HEAD_DISPENSER_OUTPUT);
CDeviceConfigDispenserController* p = CDeviceConfigDispenserController::GetInstance();
SDeviceConfigDispenser d;
p->GetData( d );
m_DispenserChInfoSet.GetChMap(m_mapCh);
for( int i = 0; i < 5; i++ ) {
m_cmbCh[i].ResetContent();
m_cmbCh[i].SetScrollCnt(5);
m_cmbCh[i].SetHitTrace( TRUE );
m_edtCh[i].Create(NULL,NULL,WS_VISIBLE|WS_CHILD|WS_DISABLED,rc,this,IDC_EDT_MT_HEAD_DISPENSER_CH1 + i);
m_edtCh[i].SetLimitTextNum(32);
int itemCnt = 0;
CString strCh;
for( map<int, CString>::iterator it = m_mapCh.begin(); it != m_mapCh.end(); it++ ) {
strCh.Format(_T("%d"), it->first);
m_cmbCh[i].InsertString(itemCnt, strCh);
m_cmbCh[i].SetItemData(itemCnt, it->first);
if( d.nUseCh[i] == it->first ) {
m_cmbCh[i].SetCurSel( itemCnt );
m_edtCh[i].SetString( it->second );
}
itemCnt++;
}
m_rdoCh[i].SetCheck( BST_UNCHECKED );
}
afx_msg LRESULT CMaintenanceHeadDispenserDlg::OnCbxSelchanged(WPARAM wParam, LPARAM lParam)
{
//int j = 0; //ou
for( int i = 0; i < 5; i++ ) {
if( m_cmbCh[i].m_hWnd == (HWND)lParam )
{
int Cnt = m_cmbCh[i].GetCount();
if( (int)wParam < Cnt && (int)wParam >= 0) {
m_cmbCh[i].SetCurSel( (int)wParam );
int Index = (int)m_cmbCh[i].GetItemData( m_cmbCh[i].GetCurSel() );
map<int, CString>::iterator it = m_mapCh.find( Index );
if( it != m_mapCh.end() ) {
m_edtCh[i].SetString( it->second );
}
break;
}
}
}

Streaming file from aws s3 through boost socket

I'm trying to connect via boost ssl socket to aws s3.
It works but when I read, I had several problem.
Corrupted files on the same file but not others.
File not corrupted (md5filter got all the data) but the data sent to the buffer are not good. Meaning there is a problem between the different layers of read somewhere but can't figure out where.
Sometimes the program get stuck in the S3_client::read function and loop thousands of times in the do-while loop calling read. But it never reaches md5filter read.
It get stuck between filterStream.read() and md5filter.read() which is not called. I don't know if it gzip or filterStream. But it only happens if there is no call to the lower layers of read for a while.
Can you help spot the problem in my code ?
#ifndef BTLOOP_AWSCLIENT_H
#define BTLOOP_AWSCLIENT_H
#include "boost/iostreams/filter/gzip.hpp"
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filtering_streambuf.hpp>
#include <boost/iostreams/categories.hpp>
#include <boost/iostreams/stream.hpp>
#include <string>
#include <set>
#include <map>
#include <openssl/md5.h>
#include <sstream>
#include <fstream>
#include <iostream>
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include "Logger.h"
namespace io = boost::iostreams;
namespace asio = boost::asio;
namespace ssl = boost::asio::ssl;
typedef ssl::stream<asio::ip::tcp::socket> ssl_socket;
namespace S3Reader
{
class MD5Filter
{
public:
typedef char char_type;
struct category :
io::multichar_input_filter_tag{};
MD5Filter( std::streamsize n );
~MD5Filter();
template<typename Source>
std::streamsize read( Source& src, char* s, std::streamsize n );
void setBigFileMode() { _bigFileMode = true; }
std::string close();
void setFileName( std::string fileName ) { _fileName = fileName; };
inline std::streamsize writtenBytes() {std::streamsize res = _writtenBytes; _writtenBytes= 0; return res;};
inline bool eof(){return _eof;};
private:
void computeMd5( char* buffer, size_t size, bool force = false );
private:
bool _bigFileMode;
int _blockCount;
std::vector<unsigned char> _bufferMD5;
MD5_CTX _mdContext;
unsigned char _hashMd5[MD5_DIGEST_LENGTH];
std::string _fileName;
std::streamsize _writtenBytes;
int _totalSize;
bool _eof;
};
class Ssl_wrapper : public io::device<io::bidirectional>
{
public:
Ssl_wrapper( ssl_socket* sock, std::streamsize n ) :
_sock( sock ),_totalSize(0) { };
std::streamsize read( char_type* s, std::streamsize n )
{
boost::system::error_code ec;
size_t rval = _sock->read_some( asio::buffer( s, n ), ec );
_totalSize +=rval;
LOG_AUDIT( " wrapperR: " << rval << " " << _totalSize << " "<<ec.message());
if ( !ec )
{
return rval;
}
else if ( ec == asio::error::eof )
return -1;
else
throw boost::system::system_error( ec, "Wrapper read_some" );
}
std::streamsize write( const char* s, std::streamsize n )
{
boost::system::error_code ec;
size_t rval = _sock->write_some( asio::buffer( s, n ), ec );
if ( !ec )
{
return rval;
}
else if ( ec == asio::error::eof )
return -1;
else
throw boost::system::system_error( ec, " Wrapper read_some" );
}
private:
ssl_socket* _sock;
int _totalSize;
};
class S3_client
{
public:
S3_client( const std::string& key_id, const std::string& key_secret, const std::string& bucket );
virtual ~S3_client();
bool open( const std::string& fileName );
int read( char* buffer, size_t size );
int readLine( char* buffer, size_t size );
void close();
bool eof() { return _filterStream.eof(); }
std::string authorize( const std::string request );
bool connectSocket( std::string url, std::string port, std::string auth );
private :
std::string _key_id;
std::string _key_secret;
std::string _bucket;
std::string _fileName;
io::gzip_decompressor _gzip;
MD5Filter _md5Filter;
boost::posix_time::seconds _timeout;
ssl_socket* _sock;
Ssl_wrapper* _wrapper;
io::stream<Ssl_wrapper>* _sockstream;
std::map<std::string, std::string> _headerMap;
io::filtering_istream _filterStream;
int _totalSize;
};
}
#endif //BTLOOP_AWSCLIENT_H
S3Client.cpp
#include "S3_client.h"
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/iostreams/copy.hpp>
#include <boost/iostreams/filter/counter.hpp>
#include <boost/exception/diagnostic_information.hpp>
#include <system/ArmError.h>
namespace io = boost::iostreams;
namespace asio = boost::asio;
namespace ssl = boost::asio::ssl;
namespace S3Reader
{
static const size_t s3_block_size = 8 * 1024 * 1024;
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64( unsigned char c )
{
return (isalnum( c ) || (c == '+') || (c == '/'));
}
std::string url_encode( const std::string& value )
{
std::ostringstream escaped;
escaped.fill( '0' );
escaped << std::hex;
for ( auto i = value.begin(), n = value.end(); i != n; ++i )
{
auto c = *i;
if ( isalnum( c ) || c == '-' || c == '_' || c == '.' || c == '~' )
{
escaped << c;
continue;
}
escaped << std::uppercase;
escaped << '%' << std::setw( 2 ) << int((unsigned char) c );
escaped << std::nouppercase;
}
return escaped.str();
}
std::string base64_encode( unsigned char const* bytes_to_encode, unsigned int in_len )
{
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while ( in_len-- )
{
char_array_3[i++] = *(bytes_to_encode++);
if ( i == 3 )
{
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for ( i = 0; (i < 4); i++ )
ret += base64_chars[char_array_4[i]];
i = 0;
}
}
if ( i )
{
for ( j = i; j < 3; j++ )
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for ( j = 0; (j < i + 1); j++ )
ret += base64_chars[char_array_4[j]];
while ((i++ < 3))
ret += '=';
}
return ret;
}
std::string to_hex( const uint8_t* buffer, size_t buffer_size )
{
std::stringstream sst;
for ( uint i = 0; i < buffer_size; i++ )
{
sst << std::setw( 2 ) << std::setfill( '0' ) << std::hex << int( buffer[i] );
}
return sst.str();
}
std::string getDateForHeader( bool amzFormat )
{
time_t lt;
time( &lt );
struct tm* tmTmp;
tmTmp = gmtime( &lt );
char buf[50];
if ( amzFormat )
{
strftime( buf, 50, "Date: %a, %d %b %Y %X +0000", tmTmp );
return std::string( buf );
}
else
{
tmTmp->tm_hour++;
//strftime( buf, 50, "%a, %d %b %Y %X +0000", tmTmp );
std::stringstream ss;
ss << mktime( tmTmp );
return ss.str();
}
}
MD5Filter::MD5Filter( std::streamsize n ) :
_bigFileMode( false ), _blockCount( 0 ), _writtenBytes(0), _totalSize( 0 )
{
MD5_Init( &_mdContext );
memset( _hashMd5, 0, MD5_DIGEST_LENGTH );
}
MD5Filter::~MD5Filter()
{
close();
}
template<typename Source>
std::streamsize MD5Filter::read( Source& src, char* s, std::streamsize n )
{
int result =0;
try
{
if ((result = io::read( src, s, n )) == -1 )
{
_eof=true;
LOG_AUDIT( _fileName << " md5R: " << result << " " << _totalSize );
return -1;
}
}
catch ( boost::exception& ex)
{
LOG_ERROR( _fileName <<" "<< boost::diagnostic_information(ex)<< " " << result );
}
computeMd5( s, (size_t) result );
_totalSize += result;
_writtenBytes = result;
LOG_AUDIT( _fileName << " md5R: " << result << " " << _totalSize );
return result;
}
void MD5Filter::computeMd5( char* buffer, size_t size, bool force )
{
size_t realSize = s3_block_size;
uint8_t blockMd5[MD5_DIGEST_LENGTH];
if ( !_bigFileMode )
{
MD5_Update( &_mdContext, buffer, size );
return;
}
if ( size > 0 )
{
_bufferMD5.insert( _bufferMD5.end(), &buffer[0], &buffer[size] );
}
if ((_bufferMD5.size() < s3_block_size) && !force )
return;
if ( force )
realSize = _bufferMD5.size();
MD5( &_bufferMD5[0], realSize, blockMd5 );
MD5_Update( &_mdContext, blockMd5, MD5_DIGEST_LENGTH );
_blockCount++;
if ( _bufferMD5.size() == s3_block_size )
{
_bufferMD5.clear();
return;
}
if ( force )
return;
memcpy( &_bufferMD5[0], &_bufferMD5[s3_block_size], _bufferMD5.size() - s3_block_size );
_bufferMD5.erase( _bufferMD5.begin() + s3_block_size, _bufferMD5.end());
}
std::string MD5Filter::close()
{
std::string mdOutput;
computeMd5( NULL, 0, true );
MD5_Final( _hashMd5, &_mdContext );
mdOutput = to_hex( _hashMd5, MD5_DIGEST_LENGTH );
if ( _bigFileMode )
{
mdOutput += "-" + boost::lexical_cast<std::string>( _blockCount );
}
return mdOutput;
}
std::string S3_client::authorize( const std::string request )
{
unsigned char* digest;
digest = HMAC( EVP_sha1(), _key_secret.c_str(), (int) _key_secret.size(), (unsigned char*) request.c_str(), (int) request.size(), NULL, NULL );
std::string signature( url_encode( base64_encode( digest, 20 )));
return "?AWSAccessKeyId=" + _key_id + "&Expires=" + getDateForHeader( false ) + "&Signature=" + signature;
}
S3_client::S3_client( const std::string& key_id, const std::string& key_secret, const std::string& bucket ) :
_key_id( key_id ), _key_secret( key_secret ), _bucket( bucket ), _gzip( io::gzip::default_window_bits, 1024 * 1024 )
, _md5Filter( s3_block_size ), _timeout( boost::posix_time::seconds( 1 )), _totalSize( 0 ) { }
S3_client::~S3_client()
{
close();
}
bool S3_client::connectSocket( std::string url, std::string port, std::string auth )
{
std::string amzDate = getDateForHeader( true );
std::string host = "url";
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver( io_service );
boost::asio::ip::tcp::resolver::query query( url, "https" );
auto endpoint = resolver.resolve( query );
// Context with default path
ssl::context ctx( ssl::context::sslv23 );
ctx.set_default_verify_paths();
_sock = new ssl_socket( io_service, ctx );
boost::asio::socket_base::keep_alive option( true );
_wrapper = new Ssl_wrapper( _sock, s3_block_size );
_sockstream = new io::stream<Ssl_wrapper>( boost::ref( *_wrapper ));
asio::connect( _sock->lowest_layer(), endpoint );
_sock->set_verify_mode( ssl::verify_peer );
_sock->set_verify_callback( ssl::rfc2818_verification( url ));
_sock->handshake( ssl_socket::client );
_sock->lowest_layer().set_option( option );
std::stringstream ss;
ss << "GET " << _fileName << auth << " HTTP/1.1\r\n" << "Host: " << host << "\r\nAccept: */*\r\n\r\n";
_sockstream->write( ss.str().c_str(), ss.str().size());
_sockstream->flush();
std::string http_version;
int status_code = 0;
(*_sockstream) >> http_version;
(*_sockstream) >> status_code;
if ( !_sockstream || http_version.substr( 0, 5 ) != "HTTP/" )
{
std::cout << "Invalid response: " << http_version << " " << status_code << std::endl;
return false;
}
if ( status_code != 200 )
{
std::cout << "Response returned with status code " << http_version << " " << status_code << std::endl;
return false;
}
return true;
}
bool S3_client::open( const std::string& fileName )
{
std::string port = "443";
std::string url = "bucket";
std::stringstream authRequest;
std::string date = getDateForHeader( false );
_fileName = fileName;
authRequest << "GET\n\n\n" << date << "\n/" << _bucket << "" << fileName;
std::string auth = authorize( authRequest.str());
if ( !connectSocket( url, port, auth ))
THROW( "Failed to open socket" );
std::string header;
while ( std::getline( *_sockstream, header ) && header != "\r" )
{
std::vector<std::string> vectLine;
boost::split( vectLine, header, boost::is_any_of( ":" ));
if ( vectLine.size() < 2 )
continue;
boost::erase_all( vectLine[1], "\"" );
boost::erase_all( vectLine[1], "\r" );
boost::erase_all( vectLine[1], " " );
_headerMap[vectLine[0]] = vectLine[1];
}
if ( _headerMap.find( "Content-Length" ) == _headerMap.end())
return false;
if ( _headerMap.find( "Content-Type" ) == _headerMap.end())
return false;
if ((uint) std::atoi( _headerMap.at( "Content-Length" ).c_str()) > s3_block_size )
_md5Filter.setBigFileMode();
_md5Filter.setFileName( _fileName );
if ( _headerMap["Content-Type"] == "binary/octet-stream" )
_filterStream.push( _gzip, s3_block_size );
_filterStream.push( boost::ref( _md5Filter ), s3_block_size );
_filterStream.push( boost::ref( *_sockstream ), s3_block_size );
return true;
}
void S3_client::close()
{
std::string localMD5 = _md5Filter.close();
std::string headerMD5 = _headerMap["ETag"];
if ( localMD5 != headerMD5 )
THROW ( "Corrupted file " << _fileName << " " << localMD5 << " " << headerMD5 << "." );
else
LOG_AUDIT( "Close S3: " << _fileName << " " << localMD5 << " " << headerMD5 << "." );
}
int S3_client::readLine( char* buffer, size_t size )
{
_filterStream.getline( buffer, size );
return _filterStream.gcount();
}
int S3_client::read( char* buffer, size_t size )
{
std::streamsize sizeRead = 0;
do
{
_filterStream.read( buffer, size );
sizeRead = _md5Filter.writtenBytes();
_totalSize += sizeRead;
LOG_AUDIT( _fileName << " s3R: " << sizeRead << " " << _totalSize );
}
while( sizeRead ==0 && !_md5Filter.eof() && !_sockstream->eof() && _filterStream.good() && _sock->next_layer().is_open());
return sizeRead;
}
}
int main( int argc, char** argv )
{
S3Reader::S3_client client( key_id, key_secret, s3_bucket );
client.open("MyFile");
while (client.read(buffer, bufferSize) >0 ) {}
}

Using a pointer to my arrays gives me an "Unhandled exception" in C++?

Here's the full code for reference:
#include <SDL.h> /* SDL stuff */
#include <SDL_video.h> /* surfaces,screen,renderer */
#include <SDL_keyboard.h> /* to handle kbd input */
#include <cstdlib> /*srand,rand*/
#include <iostream> /* cout,cin */
#include <time.h> /* time */
#define NUMFLAKES 128
#define NUMLOOPS (NUMFLAKES >> 1)
//setup the putpixel function
void putpixel( SDL_Renderer* renderer,int &x,int &y,SDL_Color &pxl )
{
SDL_SetRenderDrawColor( renderer, pxl.r,pxl.g,pxl.b,pxl.a );
SDL_RenderDrawPoint( renderer,x,y );
}
int quitFunc( SDL_Surface *screen,SDL_Texture *texdisp,SDL_Renderer *renderer,SDL_Window *window );
int main( int argc,char *args[] )
{
std::ios::sync_with_stdio( false ); //make iostream a bit snappier by stopping sync with stdio
//Start SDL
int initret = SDL_Init( SDL_INIT_VIDEO | SDL_INIT_EVENTS );
switch( initret ) {
case true:
std::cout << "SDL_Init: Couldn't start SDL...\n" << SDL_GetError() << std::endl; break;
default: break;
}
SDL_DisplayMode fulldisp;
SDL_GetCurrentDisplayMode( 0,&fulldisp );
//The attributes of the screen
const int PX_WIDTH = (int)(fulldisp.w / 1.5);
const int PX_HEIGHT = (int)(fulldisp.h / 1.5);
int xo[NUMFLAKES] = {};
int yo[NUMFLAKES] = {};
int *x = &xo[NUMFLAKES]; //fix this bullshit
int *y = &yo[NUMFLAKES];
//To define the current window
SDL_Window* window = SDL_CreateWindow( "SDL Snowflakes",
SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,
PX_WIDTH,PX_HEIGHT,SDL_WINDOW_SHOWN );
//The surface using the window defined above
SDL_Surface* screen = SDL_GetWindowSurface( window );
SDL_ShowCursor(1);
/* Set up renderer */
SDL_Renderer* renderer = SDL_CreateRenderer( window,-1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE | SDL_RENDERER_PRESENTVSYNC );
/* render to texture */
SDL_Texture* texdisp = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGB888,
SDL_TEXTUREACCESS_TARGET,PX_WIDTH,PX_HEIGHT);
SDL_SetRenderTarget( renderer,texdisp );
SDL_UpdateWindowSurfaceRects( window,NULL,NUMFLAKES );
SDL_SetRenderDrawColor( renderer,0,0,0,0 );
SDL_RenderClear( renderer );
//colours for putpixel
SDL_Color white;
SDL_Color rndcol;
white = { 0xFF,0xFF,0xFF,0xFF };
rndcol = { rand() % 255,rand() % 255,rand() % 255,0xFF };
//If there was an error in setting up the screen
switch((bool)(screen)) {
case 0:
SDL_Quit(); return 1; break;
default:
std::cout << "Created window of size: " << PX_WIDTH << "x" << PX_HEIGHT << std::endl;
break;
}
SDL_Event sdlevent;
SDL_PollEvent( &sdlevent );
//Setup Snow Flakes
SDL_Rect putfr; //Rect for updating the screen
int flake = NUMFLAKES;
int *pFlake = &flake;
srand( ( unsigned )time( NULL ) );
for( *pFlake = 0; *pFlake < NUMFLAKES; (*pFlake)++ )
{
(*x)[ pFlake ] = rand() % PX_WIDTH;
(*y)[ pFlake ] = rand() % ( int )( PX_HEIGHT / 1.5 );
xo[ *pFlake ] = (*x)[ pFlake ];
yo[ *pFlake ] = (*y)[ pFlake ];
std::cout << "Set origin..." << (*x)[ pFlake ] << "," << (*y)[ pFlake ]
<< "\nAt address->" << y[ *pFlake ] << "," << y[ *pFlake ] << std::endl;
putpixel( renderer,(*x)[ pFlake ],(*y)[ pFlake ],white );
/* Intended to only update what changed on screen, still working on it, ignore this */
putfr.x = (*x)[ pFlake ];
putfr.y = (*y)[ pFlake ];
SDL_SetRenderTarget( renderer,NULL );
SDL_RenderCopy( renderer,texdisp,NULL,&putfr );
SDL_RenderPresent( renderer );
}
int move,movex,movey;
for( int loop = 0; loop <= NUMLOOPS && (bool)(sdlevent.type != SDL_QUIT); loop++ )
{
for( (*pFlake) = 0; (*pFlake) < NUMFLAKES && sdlevent.type != SDL_QUIT; (*pFlake)++,SDL_PollEvent( &sdlevent ) )
{
//resetting rndcol
rndcol = { rand() % 255,rand() % 255,rand() % 255 };
// choose whether to move left, right or straight down and by how many pixels
move = rand() % 3;
movex = ( rand() % 2 ) + 1;
movey = ( rand() % 5 ) + 1;
//backup the existing positions
xo[ *pFlake ] = (*x)[ pFlake ];
yo[ *pFlake ] = (*y)[ pFlake ];
// now draw again
putpixel( renderer,(*x)[ pFlake ],(*y)[ pFlake ],rndcol );
// move down the screen by the no of movey
if( (*y)[ pFlake ] + ( movey + 1 ) < PX_HEIGHT )
{
(*y)[ pFlake ] = (*y)[ pFlake ] + ( movey + 1 );
} else {
putpixel( renderer,(*x)[ pFlake ],(*y)[ pFlake ],rndcol );
(*y)[ pFlake ] = rand() % ( PX_HEIGHT / 2 );
}
if( (*x)[ pFlake ] < 0 ) {
(*x)[ pFlake ] = movex;
}
if( (*x)[ pFlake ] > PX_WIDTH ) {
(*x)[ pFlake ] = ( PX_WIDTH - movex );
}
// if 0 then left, 1 for right, else straight down
switch( move ) {
case 0:
(*x)[ &pFlake ] = (*x)[ &pFlake ] - movex; break;
case 1:
(*x)[ &pFlake ] = (*x)[ &pFlake ] + movex; break;
}
putpixel( renderer,(*x)[ pFlake ],(*y)[ pFlake ],rndcol );
}
//Renderer needs only to update what changes
putfr.x = xo[ *pFlake ];
putfr.y = yo[ *pFlake ];
SDL_SetRenderTarget( renderer,NULL );
SDL_RenderCopy( renderer,texdisp,&putfr,&putfr );
SDL_RenderPresent( renderer );
SDL_Delay(128);
//std::cout << "Completed " << loop << " loops" << std::endl;
}
quitFunc( screen,texdisp,renderer,window );
return 0; //just to stop compiler warning
}
int quitFunc( SDL_Surface *screen,SDL_Texture *texdisp,SDL_Renderer *renderer,SDL_Window *window )
{
SDL_FreeSurface( screen ); // Destroy things before SDL_Quit
SDL_DestroyTexture( texdisp );
SDL_DestroyRenderer( renderer );
SDL_DestroyWindow( window );
std::cout << "\nDestroyed SDL objects, calling SDL_Quit()..." << std::endl;
SDL_Quit();
std::cout << "\nAccomplished SDL_Quit\n" << std::endl;
return 0;
}
I'm trying to use pointers to x[] and y[] (Not an array of pointers, but a pointer to the array) to make the program just use those objects, instead of making copies and changing those.
This is pretty much just to lean toward processing efficiency/minimizing the program footprint, as the arrays could get too big at certain points and copying those might take too much time.
I have also tried:
int *x = { &xo[NUMFLAKES] };
int *y = { &yo[NUMFLAKES] };
Which gave me the same error. I know that I'm probably using pointers incorrectly (I think it's trying to access the wrong memory?), but I'm unsure of how to do it the correct way.
I suspect that the issue is
int *x = &xo[NUMFLAKES];
This is initializing the pointer x to point to the address of the NUMFLAKES element of the array - one past the end of the array. That is not likely what you meant. Perhaps
int *x = &xo[0]?
This sets the pointer to the address of the first element of the array, allowing you to use x as an alias for xo.
The error is here: int *x = &xo[NUMFLAKES];
You are trying to access the index 128 (NUMFLAKES) of an array of size 128. This index (128) is out of bound since the index start at 0.
You can achieve what you are looking for with the following:
int *p;
int xo[NUMFLAKES];
p = xo; // <-- Now p is pointing to the first element of xO

Reading a config file

I'm trying to read a config file like this:
rawfile=input.raw
encfile=encoded.enc
decfile=decoded.raw
width=512
height=512
rle=1
quantfile=matrix.txt
logfile=log.txt
Having this function:
void Compression::readConfigFile(char * input)
{
string lineBuf;
string optionBuf;
std::ifstream confFile(input);
if ( confFile.is_open() )
{
while ( getline( confFile, lineBuf ) )
{
optionBuf = "rawfile=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->rawfile = lineBuf.c_str();
}
optionBuf = "encfile=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->encfile = lineBuf.c_str();
}
optionBuf = "decfile=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->encfile = lineBuf.c_str();
}
optionBuf = "width=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->width = atoi( lineBuf.c_str() );
}
optionBuf = "height=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->height = atoi( lineBuf.c_str() );
}
optionBuf = "rle=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->rle = atoi( lineBuf.c_str() );
}
optionBuf = "quantfile=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length());
this->matrix = lineBuf.c_str();
}
optionBuf = "logfile=";
if ( ( ( int )lineBuf.find(optionBuf) ) != -1 )
{
lineBuf.erase( 0, optionBuf.length() );
this->logfile = lineBuf.c_str();
}
confFile.close();
}
}
else
cout << "Can't open file: " << input << endl;
}
But it doesn't work. My ints are 0 or some big number. My strings are still empty.
Can someone help me please?
Kind regards,
shouldn't you rather close the file outside of the while loop ?
while() {
...
}
confFile.close();