Friday, May 24, 2013

Rewinding Variadic Lists

/* Written as a personal challenge; it is possible to rewind a Variadic list; in fact it's extremely easy, as it is based on the use of pointers, which have a definitive size in memory, so you can move up and down the list simply by adjust the pointer of the list.  In this example this was accomplished using the sizeof function and adjust the list pointer by iterations of this (I believe it's 4 bytes, but I might be wrong about that).  I haven't tested this with any other type in the list (chars*, doubles, etc) but it seems like it aught to work.
 */
#include <iostream>
#include <stdarg.h>
using namespace std;
void out(int sou,...);
int main(){
    int i=0;
    out(i,3,4,5,6,0);
    cin >> i;
    return 0;
}
void out(int sou,...){
    int r=0,i=1;
    va_list test;
    int start=sizeof(test);/*this grabs the size of the pointer*/
    va_start(test,sou);
    while(r=va_arg(test,int)){
        cout << "int = " << r << ":"<<(int)test << endl;
        i++;/*this counts the number of parameters passed to the function*/
        }
    test-=start*i;//this rewinds the pointer to the start of the list
    while(r=va_arg(test,int)){
        cout<<r<<endl;
        }
    va_end(test);
    va_list test2;
    va_start(test2,sou);/*this is just provided as a second method of "rewinding the list" though is less efficient*/
    while(r=va_arg(test2,int))cout << "int = " << r << ":"<<(int)test << endl;
    va_end(test2);
}

Thursday, May 23, 2013

Variadic Example #3

/*  Here's one more example on using variadic functions that I was playing with.  This on scans an entered string and looks for '!', reporting if it's found with "DETECTED", then applies a few different treatments to the string depending on what int parameters are sent down.  Mostly I did this to see if I could, with the idea being: could it be possible to pseudo-replicate what happens with a "printf" function?
 */
#include <iostream>
#include <stdarg.h>
using namespace std;

void newp(char* dat,...);

int main(){
    char rr[99];
    int ii=999;
    cout<<"Enter a string:";
    cin >> rr;
    newp(rr,1,2,1,3,1);
    cin >> ii;
   
}
void newp(char* dat,...){
     char gist;
     va_list o;
     int i=0,j=strlen(dat),k=0;
     for(k;k<j;k++){
         if(dat[k]=='!')cout<<"DETECTED!"<<endl;
     }
     va_start(o,dat);
     while(gist=va_arg(o,int)){
         switch(gist){
             case 1:
                 cout << dat << dat <<endl;
                 break;
             case 2:
                 cout << endl << "WORD!" << endl;
                 break;
             case 3:
                 cout.setf(ios::right);
                 for(i=61;i<85;i++){
                     cout.width(i);
                     cout<<i<<")"<<dat;
                 }
                 cout<<endl;
                 break;
             default:
                 cout<<"Undefined parameter"<<endl;
                 break;
         }
     }
}

Variadic Function Example #2

// This is just a quick sample of another very basic variadic function; this one returns which of however many // strings are sent to it is the longest.  I think that's probably a poorly phrased sentence, but there ya go.

#include <iostream>
#include <stdarg.h>
using namespace std;
const char* longest(char* lon,...);
int main(){
    char* lon;
    int g;
    cout << longest(lon,"He","heee","heeeeee",'\0');
    cin >> g;
    return 0;
}
const char* longest(char* lon,...){
    va_list whi;
    va_start(whi,lon);
    int i=0,j=0,k=0;
    char* bonk;
    char* bink;
    while(bonk=va_arg(whi,char*)){
        for(i=0;bonk[i];i++){
            j++;
            if(j>k)bink=bonk;
        }
    }
    return bink;
}

frustration=nstrcat(des,...);(ver 1.1)

#include <iostream>
#include <stdarg.h>

const char* nstrcat(char* des,...);
void merge(char*, char*);

const char* nstrcat(char* des,...){
      va_list pass;
      va_start(pass,des);
      char* base;
      while(base=va_arg(pass,char*)){
          if(base)merge(des,base);
          else break;
      }
      va_end(pass);
      return des;
}
void merge(char* des,char* base){
     int i=0,j=0;
     for(i;des[i];i++);
     for(i;base[j];i++,j++){
         des[i]=base[j];
     }  
}
The hardest thing to wrap your head around when you first start working with va_list's (it seems to me) is the idea that each time you reference the list with va_arg it advances the the address pointer for the parameter list.  Once you figure out how to work with that the rest goes pretty easy. 

ASCTOINT 1.2 (Now with range checking,bad input rejection, and negitive numbers!)

#include <iostream>
#include <cstdlib>
#define MAX 99

int asctoint(char*);
int pow(int,int);

using namespace std;

int main(){
    char ghost[MAX];
    int alter=0;
    int p=0;
    cin >> ghost;
    alter=asctoint(ghost);
    cout << alter;
    cin >> p;
    return 0;
}
int asctoint(char* a){
    int grab[MAX];
    bool flip=false;
    int i=0,j=0;
    int num=0;
    int toast=0;
    if(a[0]=='-'){
        flip=true;
        i++;
    }
    for(i;a[i];i++,num++){
        if(a[i]>47&&a[i]<58)grab[i]=a[i]-48;
        else return 0;
    }
    if(flip){
        j++;
    }
    if(num>10)return 0;
    for(j;num>0;j++,num--){
        toast+=pow(grab[j],num);
    }
    if(flip)toast*=-1;
    return toast;
}
int pow(int dig,int exp){
    int i=0;
    if(exp>1){
        for(i=0;i<exp-1;i++){
            dig*=10;
        }
    }
    return dig;
}

ASCTOINT

ASCTOINT function:
(I didn't bother to add any boundaries on the input, but remember that an int has a practical max, and too high of a number will cause this function to return a REALLY weird number)

#include <iostream>
#include <cstdlib>
#define MAX 99
int asctoint(char*);
int pow(int,int);
using namespace std;
int main(){
    char ghost[MAX];
    int alter=0;
    int p=0;
    cin >> ghost;
    alter=asctoint(ghost);
    cout << alter;
    cin >> p;
    return 0;
}
int asctoint(char* a){
    int grab[MAX];
    int i=0,j=0;
    int num=0;
    int toast=0;
    for(i=0;a[i];i++){
        grab[i]=a[i]-48;
        num++;
    }
    for(j=0;num>0;j++,num--){                         
        toast+=pow(grab[j],num);
    }
    return toast;
}
int pow(int dig,int exp){
    int i=0;
    if(exp>1){
        for(i=0;i<exp-1;i++){
            dig*=10;
        }
    }
    return dig;
}

Tuesday, May 7, 2013

Here is the OOP344 blog, as requested.
Looking forward to this class, learning some desktop presentation libraries like conio and curses.
Should prove to be interesting.