vijayan121 1,152 Posting Virtuoso

part of the reason for you confusion is that you are trying out code with a. sizeof of the element (int) happens to be the same as the size of a pointer on your implementation. b. there are just two elements in the array.
try playing around with

double big_block[1000] ;

and try out your code on that array.

vijayan121 1,152 Posting Virtuoso
#include <iostream>
#include <string>
#include <cassert>

int main()
{
  std::string city = "Memphis" ;
  std::string state = "Tennessee" ;
  assert( city.size() < 16U ) ;

  std::string result = city ;
  result.insert( result.end(), 16U-result.size(), ' ' ) ;
  result += state ;
  std::cout << result << '\n' ; 
  
  // or
  result = city + std::string( 16U-city.size(), ' ' ) + state ;
  std::cout << result << '\n' ; 
}
vijayan121 1,152 Posting Virtuoso

so when we declare an array:
int arr[2] = {2,3};
we are taking some bytes "as a memory block"
then creating a pointer called 'arr' and pointing him to the block.

i think you are getting it wrong here. arr is not a pointer, it is the array (the 'block' as you called it). it is just that arr can be implicitly coverted to an rvalue; a pointer which points to the first element of the block.

int arr[2] = { 2, 3 };
int* ptr = arr ; // ok, arr is converted to a pointer to first element
                      // equivalent to int* ptr = (int*)arr ;
int i = 8 ; arr = &i ; // not ok. arr is not a pointer. error.
vijayan121 1,152 Posting Virtuoso

then when we using it in sizeof function
1.sizeof(arr);
its will print us the size of the whole block.

right!

2.sizeof(arr+1);
its will get to the other element address and will print the size of whole the elements that is after the second.
thats right?

no, that is not right. when you write arr+1, that is an expression. so arr is converted to an rvalue of type pointer to element of array. the result of the conversion is a pointer to the first element (at index zero). so arr+1 is really (pointer to first element) + 1; that is a pointer to the second element.
arr+1 == &(arr[1]) == &(arr[0])+1

so sizeof(arr+1) would give you the size of a pointer.

as per ISO/IEC 14882(E)
4.2 - Array-to-pointer conversion [conv.array]

-1- An lvalue or rvalue of type ``array of N T'' or ``array of unknown bound of T'' can be converted to an rvalue of type ``pointer to T.'' The result is a pointer to the first element of the array.

vijayan121 1,152 Posting Virtuoso

at the place where the definition of the array is visible, sizeof will give the size of the entire array. it is when you use the name of the array in an expression that it is treated as a pointer to the first element.

#include <iostream>
int main()
{
  int a[20] = {0};
  std::cout << sizeof(a) << '\t' << sizeof(a+1-1) << '\n' ;
}

sizeof(a) here gives the sizeof the entire array.
a+1 is an expression, here a is treated as an int*.
note: when you try to pass the array to a function, it is used in an expression!
note2: a[3] is also an expression!, it means *(a+3); a is treated as a pointer to the first element
note3: a itself is not a pointer; it is converted to one. so, for example, trying to assign some value to a will make the compiler really angry.

vijayan121 1,152 Posting Virtuoso

get to the command line terminal, cd to the directory and type
copy /A *.txt all.txt
you will get one big text file. i'm not sure about microsoft (or any other) word, but it should be possible to convert a text file to a word processing document.

Salem commented: Gotta love 1-line simplicity +6
vijayan121 1,152 Posting Virtuoso

I have used fgets, and managed to read all the parts of my file, 3 lines. When i print it out they are all there. I then send it over to my server program and low and behold i have only 1 line of data.

probable reason is that you have failed to account for the null character that is appended by a call to fgets

not sure of this api business, but i am using a stream socket

on a normal call to close(), the protocol stack attempts to gracefully shutdown the connection after ensuring all unsent data is sent. In the case of TCP, the stack also ensures that sent data is acknowledged by the peer. This is done in the background (after the call to close() returns), regardless of whether the socket is blocking or non-blocking.

SO_LINGER affects the behaviour of the close() operation. call setsockopt(..., SO_LINGER,...) with the following values in the linger structure; linger->l_onoff non-zero and linger->l_linger zero. close() returns immediately. The underlying stack discards any unsent data, and, in the case of connection-oriented protocols such as TCP, sends a RST (reset) to the peer (this is termed a hard or abortive close).

** warning ** it is not surprising to find the various implementations interpreting the effect of SO_LINGER differently. the purpose of SO_LINGER is very specific and only a minority of socket applications actually need it. unless you are familiar with the intricacies of TCP and BSD sockets, you could very …

vijayan121 1,152 Posting Virtuoso

...i do get the printf statement in the else but the connection stays open.

if (status==1)
     {
       printf("you should continue\n");
       printf("true = %d",status);
     }
   else
     {
       printf(" i am here but not closing\n");
       close_socket(sock);
     }

which is the socket api that you are using?

Also how can i read several lines of data from a file and store them to send over to my client. I need to search the file for matching criteria...

read one line of data by using fgets. read several lines by calling fgets in a loop and buffer the lines that are read into dynamically allocated memory.

vijayan121 1,152 Posting Virtuoso

memory for a literal string is pre-allocated (that is what static storage means). usually the memory is pre-allocated as read only.

you may be able to modify the way the compiler works by using compiler options. eg. in gcc you could use the option -fwritable-strings. this is what gcc documentation has to say about this:
-fwritable-strings
Store string constants in the writable data segment and don't uniquize them. This is for compatibility with old programs which assume they can write into string constants. Writing into string constants is a very bad idea; “constants” should be constant. This option is deprecated.

the following example may clarify things:

int main()
{
  // c1(stack) is a logical const, not a physical const
  const int c1 = 4 ;    // stack is writable at run-time
  const_cast<int&>(c1) = 200 ;  // so this wont cause a run-time fault 

  // c2 (SDA) requires dynamic init, can't be in readonly memory
  static const int c2 = strlen("abcd") ; // logical, not physical const
  const_cast<int&>(c2) = 200 ;  // so this too wont cause a run-time fault 

  // any decent compiller  will place c3 into the read-only portion of SDA
  static const int c3 = 4 ;  // logical and physical const
  
  // uncomment this & there will be a run-time fault
  //const_cast<int&>(c3) = 200 ;   
}
vijayan121 1,152 Posting Virtuoso

...i was wondering why its compiles?? ... If the literal string "hi" is constant and here we are trying to change/modify the constant:
*str = 's';
someone know?

this is what the c++ standard states:
1 A string literal is a sequence of characters (as defined in _lex.ccon_) surrounded by double quotes, optionally beginning with the letter L, as in "..." or L"...". A string literal that does not begin with L is an ordinary string literal, also referred to as a narrow string literal. An ordinary string literal has type "array of n const char" and static storage duration, where n is the size of the string as defined below, and is initialized with the given characters. A string literal that begins with L, such as L"asdf", is a wide string literal. A wide string literal has type "array of n const wchar_t" and has static storage duration, where n is the size of the string as defined below, and is initialized with the given characters.

2 Whether all string literals are distinct (that is, are stored in nonoverlapping objects) is implementation-defined. The effect of attempting to modify a string literal is undefined.

since the standard states that string literal has type "array of n const char", typing it as a char* is incorrect; a conformant implementation could (should? i would say so) give a compile-time error for

char* str = "literal"
vijayan121 1,152 Posting Virtuoso

looks like a buffer overflow in the line

fscanf(fp, "%s %s %s %s",part1,part2,part3,part4);

the contents of the file is something that is not under programmatic control; a secure alternative should be used.

vijayan121 1,152 Posting Virtuoso

as a matter of principle, do not write

char *ptr = "String Literal";

even if your compiler does not complain about it.
instead always write

const char* ptr = "String Literal"; 
const char* const ptr2 = "another literal" ; // more usual

programming is much simpler if you habitually do the correct thing. and const-correctness is something most programmers find difficult to get right at a late stage in their programming career. (if you have any doubts about this, just take a look at code snippets / tutorials / replies to threads in this site.)

vijayan121 1,152 Posting Virtuoso

processes do not have names; images (executable files) usually have names.

vijayan121 1,152 Posting Virtuoso

... I can not take tap position and calculate my new bit. of course another poblem is shifting but ...

ok, jerry. here is an implementation in C++; i have written it in C++ because a. i find it easier to explain bit-wise operations in code rather than in words. b. writing it in C would be me doing your homework. my suggestion is: ignore the C++ syntax, focus on the logic instead. and if you can treat this as psuedocode and rewrite it in C, you would have solved the problem yourself.

#include<iostream>
#include <bitset>
#include <string>
#include <set>
#include <iomanip>
using namespace std ;

enum { NBITS = 8 };
typedef bitset<NBITS>  shift_register ;
enum bit { zero=0, one=1 };

// returns the bit shifted out
bit shift( shift_register& value, const shift_register& tap_sequence ) ;

int main()
{
  cout << "shift register value (" << NBITS << " bits[0/1]): " ; 
  string value_string ; cin >> value_string ;
  shift_register value( value_string ) ;
  cout <<   value[0] << '\n' ;

  string tap_string  = "10110010" ; // a good tap sequence for 8 bits 
  //cout << "tap_sequence: (" << NBITS << " bits[0/1]): " ;
  //cin >> tap_string ;
  shift_register tap_sequence( tap_string ) ;

  cout << "value: " << value << "\ttap_sequence: " << tap_sequence << '\n' ;

  set<unsigned long> number_stream ; // numbers generated so far
  int period = 0 ;
  while(true)
  {
     string number_string ;
     static const char* const literal_bit = "01" ;
     
     // get the next …
~s.o.s~ commented: A good concept of help without actually doing the homework. +19
vijayan121 1,152 Posting Virtuoso

more simple is how can LFSR work :)

see: http://homepage.mac.com/afj/lfsr.html

vijayan121 1,152 Posting Virtuoso

for checking if word is Palindrome-madam-. or not by push half of the word in a stack and then compare it with the other half of the word)

why do you need a stack at all?

template< typename CHAR_TYPE>
inline bool is_palindrome( const CHAR_TYPE* begin )
{
  const CHAR_TYPE* end = begin ;
  while( *end ) ++end ;
  while( begin < end )
    if( *begin++ != *--end ) return false ;
  return true ;
}

strlen is not used as the original function was polymorphic on the charater type.

vijayan121 1,152 Posting Virtuoso

I've added an adaptation of this into my program. I print out cpu_time_used in floating point format. Is this value in seconds, because I have divided by CLOCKS_PER_SEC?

yes, it is in seconds. and it is completely portable. (ANSI/POSIX)
you would need to write platform specific code if and only if you find that the resolution of CLOCKS_PER_SEC is too low for your purposes on a particular system.

vijayan121 1,152 Posting Virtuoso

nonetheless, i found out that clock() works different depending on which compiler you are working... 4 example... in dev c++, i measured clock measured 1/1000... but turbo c++ measured 1/20...

the thing is... i don't know why...

clock_t start, end;
double cpu_time_used;
start = clock();   
/* whatever */
end = clock();
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
vijayan121 1,152 Posting Virtuoso

I was having trouble throwing extra parameters at the STL functions, so I had been using... erm... a global variable... That syntax helped me a ton!

when you get the time, check out the header <functional>. it has a number of function objects and things that operate on function objects (generic binders being one of them).
and if you find that interesting, check out boost::bind and boost::lambda. those should really excite you.

vijayan121 1,152 Posting Virtuoso

EDIT: And, I thought pop_back() will always remove the LAST element in a vector.
The code still works, I'm just a tad confused on how it does so :)

remove or remove_if does not really remove an element (in the sense that erase or pop_back does), it rearranges the sequence so that the elements which satisfy the condition are towards the end of the sequence; those which do not are towards the beginning. and their relative position is undisturbed. and it returns an iterator to the first element that satisfies the condition.
i assumed that there would be at most one such element; so a pop_back would erase it. narue assumed that there could be more than one; so an erase from there upto end would erase all of them.

infact remove does more or less the same thing that the partition algorithm does; in this case partition would have been faster (as the iterator for the vector can be used bidirectionally). i went along with the remove_if because it had already been mentioned, thought it might be less confusing!

vijayan121 1,152 Posting Virtuoso

Could someone explain to me how the

explicit eq_course_number( int n ) : course_num(n) {}

works?

eq_course_number is a class and the line you are referring to is the constructor. logically, the == operation is a binary one; the remove_if requires a unary predicate. so we have an object which stores the extra information in a member variable and uses it as the second parameter when the function ( operator() ) is called with just one parameter. in c++ jargon, this is called binding an argument.

the explicit keyword disables an implicit conversion from an int to an object of type eq_course_number. it does not affect anything else.

vijayan121 1,152 Posting Virtuoso

An array of objects should be handled in a similar fashion to an array of ints or strings for that matter.

this is possible only if there is an accessible default constructor.

vijayan121 1,152 Posting Virtuoso
if( remove_if ( cache.begin(), cache.end(),
                      eq_course_number(target) ) != cache.end() )
      cache.pop_back() ;

this will remove only one object; i'd assumed that courses in the cache would be unique. if you want to remove many elements which have the same course number, it needs to be written as Narue had suggested.

cache.erase( remove_if ( cache.begin(), cache.end(),
                      eq_course_number(target) ), cache.end() ) ;

this would also work if there is just one element or even none at all.

vijayan121 1,152 Posting Virtuoso
struct eq_course_number
{
  explicit eq_course_number( int n ) : course_num(n) {}
  bool operator() ( const course& c ) const
  { return c.get_number() == course_num ; }
  int course_num ;
};

//
cin >> target;
if( remove_if ( cache.begin(), cache.end(),
                      eq_course_number(target) ) != cache.end() )
      cache.pop_back() ;

an alternative is to overload operator== to test for equivalence between course and an integer course_number. then remove could be used (as in Narue's post)

vijayan121 1,152 Posting Virtuoso
void read_it_in( const char* file_name, vec_2d& vec )
{
  ifstream file(file_name) ; assert(file) ;
  size_t row, col ; file >> row >> col ; 
  vec.clear() ; vec.resize(row) ;
  string line ; 
  getline( file, line ) ; // ignore rest of first line
  for( size_t i=0 ; i<row ; ++i )
  {
    assert( getline( file, line ) ) ;
    istringstream stm(line) ;
    istream_iterator<int> begin(stm), end ;
    copy( begin, end, back_inserter(vec[i]) ) ;
    assert( vec[i].size() == col ) ;
  }
}

there is a beginner's error in the code (line 10). it should have been

void read_it_in( const char* file_name, vec_2d& vec )
{
  ifstream file(file_name) ; assert(file) ;
  size_t row, col ; file >> row >> col ; 
  vec.clear() ; vec.resize(row) ;
  string line ; 
  getline( file, line ) ; // ignore rest of first line
  for( size_t i=0 ; i<row ; ++i )
  {
    getline( file, line ) ;
    assert( file ) ;
    istringstream stm(line) ;
    istream_iterator<int> begin(stm), end ;
    copy( begin, end, back_inserter(vec[i]) ) ;
    assert( vec[i].size() == col ) ;
  }
}

caused by my penchant, as already pointed out by Rashakil Fol, to do too much in one line of code. clearly not a good habit to have developed.

vijayan121 1,152 Posting Virtuoso

just to reinforce what narue and salem have stated (more than once), here is a quote from someone who has dedicated a lifetime on doing things efficiently (and elegantly) in code:
"Premature optimization is the root of all evil (or at least most of it) in programming." - Donald Knuth

vijayan121 1,152 Posting Virtuoso

unless the size is known at compile time, or there is an externally imposed constraint, it would be easier and less error prone to use a std::vector rather than a c-style array.

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <cassert>
#include <algorithm>
#include <iterator>
using namespace std ;

typedef vector< vector<int> > vec_2d ;

void read_it_in( const char* file_name, vec_2d& vec )
{
  ifstream file(file_name) ; assert(file) ;
  size_t row, col ; file >> row >> col ; 
  vec.clear() ; vec.resize(row) ;
  string line ; 
  getline( file, line ) ; // ignore rest of first line
  for( size_t i=0 ; i<row ; ++i )
  {
    assert( getline( file, line ) ) ;
    istringstream stm(line) ;
    istream_iterator<int> begin(stm), end ;
    copy( begin, end, back_inserter(vec[i]) ) ;
    assert( vec[i].size() == col ) ;
  }
}

int main()
{
  vec_2d vec ;
  read_it_in( "test.txt", vec ) ;
  for( size_t i=0 ; i<vec.size() ; ++i )
  {
    copy(  vec[i].begin(), vec[i].end(), ostream_iterator<int>(cout,"\t") ) ;
    cout << '\n' ;
  }
}
vijayan121 1,152 Posting Virtuoso

great. and perhaps you could start calling a destructor a destructor (not a deconstructor).

vijayan121 1,152 Posting Virtuoso

That is why I'm using CIN.GET() so I can see what's being output to the screen.

cin.get() is inside main; destructors of statics are called (in reverse order of construction) after main returns (or exit is called). put your cin.get() as the last statement in your destructor (if that is the way you want to make a window stay).

vijayan121 1,152 Posting Virtuoso

I'm using Bloodshed C++ compiler, I am starting to think it's a compiler issue. But I compiled it using Vis C++, no deals?

whatever you are using, if it does not cause the destructor of statics to be called (unless abort() was called), it is not a C++ compiler. the probable reason though, is that the window is disappearing too fast for you to make out what is going on.

vijayan121 1,152 Posting Virtuoso

it does print CleanUP; try it from the command line in a terminal.
instead of (double) clicking the executable.

vijayan121 1,152 Posting Virtuoso

Maybe

int i = p * q << 12;
int j = (i >> (sizeof(int)-1) * CHAR_BIT) & (~0xF)
i = (i & j) | (~ j);

this would be about twice as slow as the original code.
and the code size would also be close to double the original.
(unless the compiler is smart enough to rewite it.)

vijayan121 1,152 Posting Virtuoso

do not allow attempt at withdraw if account has not been created.
pseudocode

void user_input()
{
  account* ac = 0 ;
  // accept user input
  // if create
  {
       if( ac == 0 )
       {
          string name ; double amt ;
          cout << "enter name <space> amount: " ;
          // assumes there are no embedded white spaces in name
          cin >> name  >> amt ; 
          ac = new account(name,amt) ;
       }
       else cerr << "account already created\n" ;
              // perhaps you can offer to delete and recreate?
  }
  // if withdraw
  if( ac == 0 ) cerr << "can't withdraw if you haven't created an account\n" ;
  else 
  {
    // accept amout
    ac->withdraw(amt) ;
  }
  delete ac ; // before you return
}
vijayan121 1,152 Posting Virtuoso

can i ask what is the purpose or use of iomanip in C++ ?

to produce formatted output, or to perform operations like flushing the stream, the stream classes privide member functions. eg.

std::cout.width(10) ;
  std::cout.fill('0') ;
  std::cout.setf( ios_base::fixed, ios_base::floatfield ) ;
  std::cout.precision(2) ;
  std::cout << 100.2 << '\n' ;
  std::cout << flush ;

this code is tedious to read (or write).

stream manipulators allow one to embed formatting information as part of the data that is sent to (recd from) the stream. eg.

std::cout <<   std::setw(10) << std::setfill('0') << std::fixed 
                << setprecision(2) << 100.2 << std::endl ;

as such they are a convenient device; they provide syntactic sugar.
jerry schwarz (who wrote the original, now obsolete, iostream library) was inspired by algol's 'layout procedures'.

vijayan121 1,152 Posting Virtuoso
#include <iostream>
#include <string>
using namespace std ;

struct account
{
  explicit account( const string& name, double amount = 0.0 ) 
    : _name(name), _amount(amount) {}
  // ...
  private:
    const string _name ;
    double _amount ;
};

int main()
{
  string name ; double amt ;
  cout << "enter name <space> amount: " ;
  // assumes there are no embedded white spaces in name
  cin >> name  >> amt ; 
  account ac1(name,amt) ;
}
vijayan121 1,152 Posting Virtuoso
vijayan121 1,152 Posting Virtuoso

If I may criticize one aspect of your code, your line if( ( rand() % ++num_nodes ) == 0 ) selected = pn ; does a bit too much in one line

true; especially in a code snippet.

Furthermore, you're using the default random number generator a bit uncarefully. The low-significance bits ...

the focus was on exposition of the algorithm, not on random number generation. if i was serious about generating pseudo random numbers, i would not use the c library rand() in any case. it often is a poor random number generator and remains a poor one even if some of its weaknesses are programmed around. a well configured mersenne_twister or lagged_fibonacci generator would produce much better results.

vijayan121 1,152 Posting Virtuoso

see thread at
http://www.daniweb.com/techtalkforums/post345699.html#post345699
this fills an array, instead of printing out the random number; but the idea is the same

vijayan121 1,152 Posting Virtuoso

you forgot to do
--required

in the for loop (line 14-16)
note: the loop could be made more efficient by adding if(required==0) break ;

vijayan121 1,152 Posting Virtuoso

the parameter passed to the function is the number of ascending random integers to be printed.
modify line 24 to
generate_ascending_number(1024);
to print 1024 numbers.

vijayan121 1,152 Posting Virtuoso

variations of this are being posted repeatedly here. hope this will clarify things once and for all.

// to choose a random element from a sequence when
//    a. you do not know how many elements are there before hand
//    b. you want to make one single pass through the sequence
//    c. you do not want to use auxiliary storage
//    algorithm:
//    step 1: select first element with probability 1
//    step 2: replace the first element with the second with  probability 1/2 
//       now both first and second are equally likely  (prob 1/2 each)
//    step 3: replace the selected with the third with  probability 1/3
//      now first, second and third are equally likely (prob 1/3 each)
//         .....
//    step n: replace the selected element with the nth with  probability 1/n
//       now any of the n are equally likely (prob 1/n each)
//    continue till end of sequence
// note: this algorithm (with appropriate modifications) can be used in 
//                   a. reading a random line from a file
//                   b. filling up an array with unique random values
//                   c. generating n random values in ascending order
//                   and so on.
//    
// here is a C implementation 
// to choose a random node from a singly linked list

#include <stdlib.h>

typedef struct node node ;
struct node {  int value ;  node* next ; };

node* choose_random_node( node* first )
{
  int num_nodes = 0 ; // nodes seen so far
  node* selected = NULL ; // selected node
  node* pn = NULL ;
  for( pn = first ; pn != NULL ; pn = pn->next )
    if(  ( rand() % ++num_nodes  ) == 0 ) selected = pn ;
  return selected ;
}
vijayan121 1,152 Posting Virtuoso

converting it to C is trivial; as you said it is only an algorithm

#include <stdio.h>
#include <time.h>
#include <stdlib.h>

void generate_ascending_rand( int N )
{
  int available = RAND_MAX ;
  int required = N ;
  int i = 0 ;
  for( ; i<available ; ++i )
    if( ( rand() % (available-i) ) < required )
    {
      --required ;
      printf( "%d\n", i ) ;
    }
}
int main()
{
  srand( (unsigned)time(NULL) ) ;
  generate_ascending_rand(50) ;
  return 0 ; // required in C
}
vijayan121 1,152 Posting Virtuoso

Actually, my idea is to run rand (not sure how many times I'll need to), and to then say for each time it returns a number, the program should check that current number with the previous one; if the current number is larger than the previous one, it gets printed to screen, if not, it gets ignored (i.e. nothing happens to it) and rand keeps going. And I'm finding that quite challenging at the moment.

rand() could return a large value (RAND_MAX for instance); your program would then loop infinitely. you will have to do something like
if the value of ( RAND_MAX - largest_so_far ) is less than random_numbers_remaining, start all over again from scratch.

if you are willing to iterate from 0 to RAND_MAX, the problem is much easier to solve.

added later

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std ;

void generate_ascending_rand( int N )
{
  int available = RAND_MAX ;
  int required = N ;

  for( int i=0 ; i<available ; ++i )
    // to choose required out of the remaining (available-i)
    if( ( rand() % (available-i) ) < required ) 
    {
      --required ;
      cout << i << '\n' ;
    }
}

int main()
{
  srand( unsigned( time(0)) ) ;
  generate_ascending_rand(50) ;
}
Thinka commented: Very helpful +3
vijayan121 1,152 Posting Virtuoso

if you are comfortable with c++ (ie. you can do more than write c code using c++ syntax), you would find the spirit recursive descent parser framework (part of the boost libraries) easy to use. internally, it uses template meta-programming techniques; but to use it productively, you just need to be familiar with mainstream c++ (primarily generic programming).

here is an example of parsing a text file:
file key_and_values.txt
------------------------------

phone_numbers = 1234, 5678 : 987,564:0:0
line 2 is a parse error
primes_2_to_19 = 2, 3, 5, 7, 11:13:17:19
primitive_pythagorian_triplet_1 = 8,15 : 7
line = 5 also an error
_12_34 = 1:2, 3:4
_daniweb_thread_numbers = 12345:56789:34567, 78901
primitive_pythagorian_triplet_2 = 9,12 : 15
adds_up_to_12 = -24 : +48 , -12

essentially it contains lines of the form
key = value, value : value.
keys have the same structure as valid c++ identifiers.
values are integers seperated by either a , or a :
white spaces are ignored.

here is a sample program that parses such a file:

#include <boost/spirit/core.hpp>
#include <boost/spirit/actor.hpp>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
using namespace std;
using namespace boost::spirit;

bool parse_it( const char* cstr, string& key, vector<int>& values )
{
    return parse( cstr,
     ( ( ( (alpha_p|'_') >> *(alnum_p|'_') )[ assign_a(key) ] ) >> ( '=' >> 
       ( int_p[ push_back_a( values ) ] >> *(  ( ch_p(',') | ':' ) >> …
MaestroS commented: Thanks for it +1
vijayan121 1,152 Posting Virtuoso

Seems I need to add the typedefs that didn't seem to inheret when i did it. Is this correct or does it work as a fluke?

this is correct; you need to have the typedefs for the iterator to work with iterator_traits<>. (specializing iterator_traits<> for your iterator is another way.) in a conformant implementation of libstdc++, you should have been able to inherit these typedefs from the iterator base class.

vijayan121 1,152 Posting Virtuoso

Horizontal is ---- not |

we need a blank hoizontal line:
<!blank> | a b c d ....
< blank> |
<!blank> | a b c d ....

vijayan121 1,152 Posting Virtuoso

Making the changes suggested gave me the errors from before:
Anachronism: using iterator_traits as a template without a declaration.
ERROR: iterator_traits is not defined.

In researching this error, i found that i need to define it properly. There are two ways. "First, define your iterator so that it has nested types I::value_type, I::difference_type, and so on. Second, you can explicitly specialize iterator_traits for your type." - SGI.com

i tested the code (with the change my_reverse_iterator< vector<int>::iterator > p(it) ; ) on vc++ 8, gcc 3.4.6 and icc 9.1; in all of them it compiles without errors or warnings.
vector<T>::iterator is fully std library compliant; it works correctly with iterator_traits<>.

vijayan121 1,152 Posting Virtuoso

Thank you! How do I create a space between each horizontal line?

change line 16 to: cout << "\n |\n" ;

vijayan121 1,152 Posting Virtuoso

the function(s) next_permutation in <algorithm> would generate the next permutation. you could call that repeatedly.

vijayan121 1,152 Posting Virtuoso

in addition to what you are currently doing, you also need to print the characters for the lines. for example:

#include <iostream>
#include <iomanip>
using namespace std;

int main() 
{
   cout << setw(4) << right << "|";
   for( int i=1; i<=10 ; ++i ) cout << left << setw(5) << i ;
   cout << "\n------------------------------------------------------\n" ;

   for( int i=1; i<=10; ++i ) 
   {
       cout << setw(3) << left << i << '|' ;
       for( int j = 1; j<=10 ; ++j )
             cout << setw(5) << left << i*j ;
       cout << endl;
   }
 }