I think its more than a year that I ask my questions about programming in this forum.Looks like its the time that I help a little too.
So I wanna put my best here.I hope it'll help some one.
Still I'll appreciate any suggestion.
Another point,It was my first time commenting my code.So I'm waiting for your opinions about it.
Thanks you all

Base.h

BaseConvert.cpp

This program converts number bases.Because of the lack of alphabets,You may encounter nonsense characters if you use bases greater than 62.
In this program I use both capital and small alphabets which means its case sensetive.
The digits are from A which is 10 to z which is 51.

Recommended Answers

All 6 Replies

Comments...

Get rid of the tabs. You can see what happens when you assume 4 spaces and Daniweb assumes 8 spaces. Convert tabs to spaces.

//Generates alphabetical digits for the given base
void genDigs(int base,char *digs){						
		
	if (base>36){							//Because for bases greater than 36,the capital alphabets are not enough
	
		for(int i=0;i<26;++i)						//Generates capital alphabets
			digs[i]=i+65;
			
		for(int i=26;i<base-10;++i)				//Generates small alphabets
			digs[i]=i+71;
			
	}
		
	else
	
		for(int i=0;i<base-10;++i)			//Generates capital alphabets for bases smaller than 36
			digs[i]=i+65;
	
}

Much nicer.

//Generates alphabetical digits for the given base
void genDigs(int base,char *digs){
    if (base>36){  //Because for bases greater than 36,the capital alphabets are not enough	
        for(int i=0;i<26;++i)	//Generates capital alphabets
            digs[i]=i+65;
			
        for(int i=26;i<base-10;++i) //Generates small alphabets
            digs[i]=i+71;			
    }	
    else
        for(int i=0;i<base-10;++i)	//Generates capital alphabets for bases smaller than 36
            digs[i]=i+65;	
}

As far as comments go, a comment would be in order when using "71". I assume it's because 71 is 97 - 26, or 'a' - 26. In which case, make life easy and do the replacement.

//Generates alphabetical digits for the given base
void genDigs(int base,char *digs){
    if (base>36){  //Because for bases greater than 36,the capital alphabets are not enough	
        for(int i=0;i<26;++i)	//Generates capital alphabets
            digs[i]=i+'A';
			
        for(int i=26;i<base-10;++i) //Generates small alphabets
            digs[i]=i+'a' - 26;			
    }	
    else
        for(int i=0;i<base-10;++i)	//Generates capital alphabets for bases smaller than 36
            digs[i]=i+'A';	
}

Maybe a constant for 26 like NUM_LETTERS. Makes the code reading easier.


Generally you'll have a file called BaseConvert.h and a file called BaseConvert.cpp. All the stuff in BaseConvert.h goes in BaseConvert.cpp. Your DECLARATIONS go in BaseConvert.h. Your implementation code goes into BaseConvert.cpp. That's usually the way things are done. Makes linking and including easier.

string Num;									//String variable for keeping final form of number
	
for(int i=0;i<digNum;++i){
    if(num[i]<10)//For elemnts smaller than 10,we can use the element itself as digits
        Num[i]=num[i]+48;
    else
        Num[i]=digs[num[i]-10]; //Otherwise it should be replaced by an alphabetical digit
}

Looks like a seg fault just waiting to happen. Use the += operator. Even if it isn't a seg fault, if you're appending a character to the end, the += operator is the way to go.

Num[i] += digs[num[i]-10];

But you've got bigger problems...

char *digs=new char; //An array for 
delete [] digs;

I don't see an "array" of chars allocated. I see ONE char allocated. But I see an "array" deleted. And I see a function that expects an array.

I didn't actually run your program. Does it compile? Does it run? Does it crash? Give good results?

Not a bad effort, however, your comments suggest that you would like some feedback...
So here are a few things that I have noticed.

First off, I don't like seeing using namespace std; anywhere, but NEVER in a header.

In function BToDec, you do this:

int *num=new int;         // This only allocatts ONE integer

fromNorm(baseNum,base,num);         // This uses num as if it is an array of size dependent
                                    // on the string baseNum. 

// ... other stuff.
delete [] num;   // definately wrong

This error is repeated throughout

Additionally, in that function you do this:

int Num; 
for(int i=n;i>0;--i)
  Num+=num[n-i]*(unsigned long int)pow(base,i-1);

Several problems with just those three lines. First you take the trouble to convert the result of pow() to an unsigned long int only to add it to a value that is only an int.
Obviously not really a good idea.
Surely the power etc could be avoided with code like this:

int Num(0); 
for(int i=0;i<n;i++)
  {
     Num*=base;
     Num+=num[i];
  }

Also you know how to use references, so get into the habit of using them, time and time again you just pass large objects by value (e.g. strings etc).

Also fromNorm just needs a re-write. What happens if base is less than 10?? e.g in line char *digs=new char[base-10]; Anyway it is good that you are trying to write an extended piece. Writing numerical code, both efficiently and robustly, is extremely taxing and will significantly improve you coding ability.

Thank you for your advices.They solved some problems of the program but I don't know how.
Stu,with my algorithm,for some numbers and bases,I got a wrong answer for the first time but a right one for further trys.Your new algorithm almost solved it.
But a new problem remains now.Sometimes when I enter a number and a base usually bigger than 20,the program terminates.As I remember,when I printed some flags,I understood it terminates while reaches new commands.But when I give one or more numbers with bases smaller than 20 and then try bases bigger,It works.
What's wrong?
this is the new code

Unfortunately, there is still lots wrong with this. It would also have helped if you had just posted your code, nobody does (or should) run executables from unknown sources.

Now to the code itself..... I am going to list a number of types of errors, but only one of each type (as I classify it, so it is very arbitrary ;)

void genDigs(int base,char *digs)
{							
  if(base<10)
    {
      digs=NULL;
      return;
  }
//....

The error here is that setting digs to null has zero effect. If you had done this *digs ='c'; , then it would have had an effect.
Reason that you still have this error: You did not turn on warnings in your compiler.
(or pay attention to them).

std::string 
toNorm(int *num,int digNum,int base)
{ 
  std::string Num;      //String variable for keeping final form of number
  char *digs=new(std::nothrow) char;      //An array for keeping digits in given base
  genDigs(base,digs);
  if (digs)
//....

you allocate ONE character, but then use digs as a multiple character array.
Either (a) allocate sufficient characters, (b) use an expandable storage, e.g. std::string. (c) make getDigs allocate the space.

You specifically use the nothrow new, and test digs AFTER using it!!!!

You use variables called num and Num, that is one small mistype away from a difficult error, and it is close to impossible to read easily. Think about your variable naming!

for(int i=0;i<digNum;++i)
   {
     if(num[i]<10)	
       Num+=num[i]+'0';
      else
        Num+=digs[num[i]-10];     
   }

The code above is what you wrote, consider this:

std::string toNorm(const int *num,const int digNum,const int base)
{
  static const char digs[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  // Tests here on the sanity of digNum, num[i]
  std::string Out;
  for(int i=0;i<digNum;i++)
    {
      // test if num[i]<0 or >base etc.
      Out+=digs[num[i]];
    }
  return Out;
}

The toNorm function I have written, that isn't that complex, but replaces some 67 lines of your code.

In short there is nothing special about base 10. you can easily avoid ALL the base<10 tests that you have.

You can also count up and divide, to avoid some of your calculation to the number of digits.


Hope this helps....

Thanks for all of your advices.They solved lots of problems.
This is the OO version of the program.

But there is one problem about it.I overloaded the insertion operator (<<) like below:

ostream& operator<<(ostream &stream,const BaseConvertor &param){
	
	stream<<param.sNum<<"("<<param.Base<<")";
	
	return stream;
	
}

I also overloaded both postfix and prefix versions of ++ and --:

BaseConvertor& BaseConvertor::operator++(){

	int base=this->Base;
	
	this->Convert(10);
	
	*this=*this+1;
	
	this->Convert(base);
	
	return *this;
	
}


BaseConvertor BaseConvertor::operator++(int){

	BaseConvertor temp=*this;
	
	int base=this->Base;
	
	this->Convert(10);
	
	*this=*this+1;
	
	this->Convert(base);
	
	return temp;
	
}

The problem is with the code below:

BaseConvertor num;
	
cin>>num;
	
cout<<"\n"<<num<<"-"<<num++<<"-"<<num<<"-"<<++num<<"\n";

If you give e.g. 5 in base 10,the output is:

7(10)-6(10)-7(10)-7(10)

But ,as you know,if you do it with an int,you will get:

5-5-6-7

what's wrong?

thanks

After some tests,I understood that the thing I mentioned above,is the normal behaviour.
As you can see,its a bit confusing and brings this question to mind:
How streams really work?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.