C Programming
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming LanguagesC Programming

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old November 8th, 2008, 12:18 AM
fmri fmri is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2008
Posts: 7 fmri User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 h 36 m 43 sec
Reputation Power: 0
Array initialization?

I'm trying to convert hexadecimal numbers to decimal values:
Code:
#include <iostream>
#include <cmath>
#include <string>

int main() {

        int d, buf[15];
        char c;

        std::cout << "decimal values: ";

        while (c=getchar()) {

                static int p=0;

                if (p>16) {
                        std::cerr << "numeric constant too long\n";
                        return 1;
                }

                switch (toupper(c)) {
                        case ' ':
                                for(int i=p-1; i>=0; i--) d+=buf[i]*pow(16, p-i);
                                std::cout << d << ' ';
                                p=0;
                                continue;
                        case '0':
                                if (p==0) { continue; }
                                else { buf[p]=0; p++; break; }
                        case 'X':
                                if (p==1) continue;
                                else { std::cerr << "unexpected character\n"; }

                        case '1': case '2': case '3': case '4': case '5':
                        case '6': case '7': case '8': case '9':
                                buf[p]=c-'0';
                                p++;
                                break;

                        case 'A': case 'B': case 'C':
                        case 'D': case 'E': case 'F':
                                buf[p]=10+toupper(c)-'A';
                                p++;
                                break;
                        default:
                                std::cerr << "unexpected character\n";
                }
        }

        std::cout << '\n';
}


This routine should permit adding a "0x" or "0X" prefix without affecting the result, but the output makes me think that an uninitialized value of buf is being written to screen. Any suggestions?

Reply With Quote
  #2  
Old November 8th, 2008, 03:06 AM
Schol-R-LEA's Avatar
Schol-R-LEA Schol-R-LEA is offline
Commie Mutant Traitor
Dev Shed Intermediate (1500 - 1999 posts)
 
Join Date: Jun 2004
Location: Norcross, GA (again)
Posts: 1,785 Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 2 Days 18 h 21 m 8 sec
Reputation Power: 1569
Setting aside the fact that you can do this with standard library functions - I am assuming that this is for a homework project - this approach won't work. You can correctly convert the value of a single numeral, but once you get into two places, you run into a problem because the bases don't align smoothly. You could only do something like this if the larger base was some simple power of the smaller one. Going from base 10 to base 16, however, you get a really messy issue of trying to add the values between place values. Given your approach, you'd have dec(42) == hex(42), since both of the numerals are under 10; but in actuality:

Code:
42 / 10 =  4 rem  2 -> 40
 2 / 10 =  2 rem  0 ->  2
                 ---------------
                       42


42 / 16 =  2 rem 10 -> 20
10 / 16 = 10 rem  0 ->  A
                 ---------------
                       2A

In point of fact, trying to convert a numeric string from one base to another directly is foolish; you'd be much better off converting the decimal string to an int, then converting the int to a hex string. While this may seem like twice as much work, the fact is that converting from a string representation to an int and back are the same operations regardless of base, and can be written a lot more easily and efficiently than you current program.

I'd also suggest that you take the conversion operations out of the main() function entirely and write separate functions for string-to-int and int-to-string which main() can then call. That makes the whole program a lot less messy and ugly all around.

The good news is, I just showed you a simple method for converting bases, right above. It has some oddities - it returns digits in reverse order - but it is quite amenable to some simple solutions. BUT... you need to be able to perform division, modulo and addition on the numbers in order to make it work, hence the two-step process when going from decimal to hex.
__________________
Rev First Speaker Schol-R-LEA;2 JAM LCF ELF KoR KCO BiWM TGIF
#define KINSEY (rand() % 7) λ Scheme is the Red Pill
Scheme in ShortUnderstanding the C/C++ Preprocessor
Taming PythonA Highly Opinionated Review of Programming Languages for the Novice, v1.1

FOR SALE: One ShapeSystem 2300 CMD, extensively modified for human use. Includes s/w for anthro, transgender, sex-appeal enhance, & Gillian Anderson and Jason D. Poit clone forms. Some wear. $4500 obo. tverres@et.ins.gov

Last edited by Schol-R-LEA : November 8th, 2008 at 03:14 AM.

Reply With Quote
  #3  
Old November 8th, 2008, 08:55 PM
fmri fmri is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2008
Posts: 7 fmri User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 h 36 m 43 sec
Reputation Power: 0
Thanks for your help. There were some counting problems that were causing unitialized parts of the array to be accessed. I tried to break this, and it seems to work:
Code:
#include <iostream>
#include <cstring>
#include <cmath>

int main() {


        std::cout << "Enter hexadecimal numbers, one at a time.\n";
        std::cout << "Separate each value with a space; <CR> to end.\n";

        char c;
        const int max=15;
        int buf[max], p=0,d=0;

        bool leading=true;

        while (c=getchar()) {
                switch (c) {

                        case '0':
                                if (!leading) { buf[p]=0; p++; }
                                break;
                        case 'x': case 'X':
                                if (!leading) {
                                        std::cerr << "unexpected char\n";
                                        return 1;
                                }
                                break;
                        case '1': case '2': case '3': case '4': case '5':
                        case '6': case '7': case '8': case '9':
                                buf[p]=c-'0';
                                p++;
                                leading=false;
                                break;
                        case 'a': case 'b': case 'c': case 'd': case 'e':
                        case 'f':

                                buf[p]=10+c-'a';
                                p++;
                                leading=false;
                                break;
                        case 'A': case 'B': case 'C': case 'D':
                        case 'E': case 'F':
                                buf[p]=10+c-'A';
                                p++;
                                leading=false;
                                break;
                        case ' ':
                                // Conversion done here
                                for (int i=p-1; i>=0; i--)
                                        d+=buf[i]*pow(16,p-1-i);
                                if (p!=0) std::cout << d << ' ';
                                p=0;
                                // Lonely prefix?
                                if (leading) std::cout << "(zero) ";
                                leading=true;
                                d=0;
                                break;
                        case '\n':
                                if (p!=0)
                                // There's a word, so convert it
                                for (int i=p-1; i>=0; i--)
                                        d+=buf[i]*pow(16,p-1-i);
                                if (p!=0) std::cout << d << '\n';
                                // Lonely prefix?
                                if (leading) std::cout << "(zero)\n";
                                return 0;
                        default:
                                std::cerr << "unexpected character\n";
                                return 1;
                }
        }
}


I'm not sure how you would modularize or simplify the code, though...how could this be condensed?

Reply With Quote
  #4  
Old November 8th, 2008, 09:14 PM
sizablegrin's Avatar
sizablegrin sizablegrin is offline
Dev Shed God 1st Plane (5500 - 5999 posts)
 
Join Date: Jun 2005
Posts: 5,964 sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 3 Weeks 2 Days 12 h 47 m 19 sec
Warnings Level: 10
Number of bans: 1
Reputation Power: 4851
Anytime you see more than two or three lines repeated you're looking at an opportunity to modularize your code. Consider the following:
Code:
...
switch (gazingus)
{
   case foo:
      do a;
      do b;
      do c;
      do z;
      break;
   case bar:
      do a;
      do b;
      do c;
      do x;
      break
...

That's ripe for the following:
Code:
...
switch (gazingus)
{
   case foo:
      doCommon ();
      do z;
      break;
   case bar:
      doCommon ();
      do x;
      break;
...

where doCommon looks like this:
Code:
void doCommon ()
{
   do a;
   do b;
   do c;
}

Furthermore, if the stuff is virtually identical, except for a couple of values, you're ripe for a function with arguments:
Code:
...
switch (gazingus)
{
   case foo:
      do a with 10;
      do b with 12;
      do c with 411;
      do z with 0;
      break;
   case bar:
      do a with 20;
      do b with 40;
      do c with 114;
      do x with 87;
      break;
...

becomes:
Code:
...
switch (gazingus)
{
   case foo:
      doCommon (10, 12, 411);
      do z with 0;
   case bar:
      doCommon (20, 40, 114);
      do x with 87.
      break;
...

Additionally, what Schol-R-Lea is telling you is that you shouldn't have a crap-pile full of code expressed in main (except possibly for exemplar purposes). Pull it out and put in an appropriately named function (handleGazingus ()) and call handleGazingus from main.
__________________
Write no code whose complexity leaves you wondering what the hell you did.
Politically Incorrect DaWei on Pointers Grumpy on Exceptions

Last edited by sizablegrin : November 8th, 2008 at 09:17 PM.

Reply With Quote
  #5  
Old November 8th, 2008, 09:30 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Dev Shed God 9th Plane (9000 - 9499 posts)
 
Join Date: Nov 2001
Location: Woodland Hills, Los Angeles County, California, USA
Posts: 9,406 Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 10 h 20 m 32 sec
Reputation Power: 4080
You could also use toupper() to reduce the number of case statements:
Code:
char foo;
...
foo = toupper(c);
switch (foo) {
   // No need to do case 'a'...'case 'f' here since toupper() ensures that
   // there aren't any lowercase characters.
}
Comments on this post
sizablegrin agrees!
__________________
Up the Irons
What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home.
"Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest
Down with Sharon Osbourne

Reply With Quote
  #6  
Old November 8th, 2008, 09:55 PM
Scorpions4ever's Avatar
Scorpions4ever Scorpions4ever is offline
Banned ;)
Dev Shed God 9th Plane (9000 - 9499 posts)
 
Join Date: Nov 2001
Location: Woodland Hills, Los Angeles County, California, USA
Posts: 9,406 Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level)Scorpions4ever User rank is General 46th Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 10 h 20 m 32 sec
Reputation Power: 4080
Of course, the best way would be to use prewritten C++ functions so you don't have to write all that conversion code. Usting stringstreams, the conversion is trivial:
Code:
#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int main(void)
{
    string input;
    cout << "Enter number to convert to decimal ";
    getline(cin, input);
    
    if (cin.fail()) {
        cerr << "Invalid input" << endl;
        return -1;
    }

    if (input[0] == '0' && 
        (input[1] == 'X' || input[1] == 'x'))
        input = input.substr(2);

    stringstream strm;
    strm << hex << input;
    int output;
    strm >> output;
    if (!strm.good() && strm.eof())
        cout << output << endl;
    else {
        cout << "Error. Could not convert " << input << endl;
        return -2;
    }

    return 0;
}

Note that most of the code above is actually error handling code. The actual conversion is all of 2 lines (the bold text)

Reply With Quote
  #7  
Old November 9th, 2008, 04:37 PM
Schol-R-LEA's Avatar
Schol-R-LEA Schol-R-LEA is offline
Commie Mutant Traitor
Dev Shed Intermediate (1500 - 1999 posts)
 
Join Date: Jun 2004
Location: Norcross, GA (again)
Posts: 1,785 Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level)Schol-R-LEA User rank is General 9th Grade (Above 100000 Reputation Level) 
Time spent in forums: 1 Month 2 Weeks 2 Days 18 h 21 m 8 sec
Reputation Power: 1569
Just out of curiosity, what was the actual assignment description, and did the instructor say anything about using a recursive function at any point? Were any recommendations made on the problem? I ask this because there is a well-known but non-intuitive recursive algorithm for this, and I'm wondering if the professor wanted you to implement that (which would have required explaining it ahead of time), or if this was supposed to see how you would solve it before showing you the general method...

Actually, let me first ask if you've covered functions and function calls yet. If you haven't then the question is moot, since you wouldn't be at that part of the course yet.

Finally, is there a specific reason why you are using C-strings instead of C++ string objects? All in all, this has the feel of a C program that has been only slightly modified to use the C++ I/O system, which makes me wonder about how the instructor is teaching this.

Last edited by Schol-R-LEA : November 9th, 2008 at 05:01 PM.

Reply With Quote
  #8  
Old November 11th, 2008, 01:32 PM
fmri fmri is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Oct 2008
Posts: 7 fmri User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 h 36 m 43 sec
Reputation Power: 0
Quote:
Originally Posted by Schol-R-LEA
Just out of curiosity, what was the actual assignment description, and did the instructor say anything about using a recursive function at any point? Were any recommendations made on the problem? I ask this because there is a well-known but non-intuitive recursive algorithm for this, and I'm wondering if the professor wanted you to implement that (which would have required explaining it ahead of time), or if this was supposed to see how you would solve it before showing you the general method...

Actually, let me first ask if you've covered functions and function calls yet. If you haven't then the question is moot, since you wouldn't be at that part of the course yet.

Finally, is there a specific reason why you are using C-strings instead of C++ string objects? All in all, this has the feel of a C program that has been only slightly modified to use the C++ I/O system, which makes me wonder about how the instructor is teaching this.


This isn't for an assignment. I'm doing the exercises out of the book on my own to try to learn C++ and relearn C. I've covered function calls and some basic things on objects and autoboxing, but the author assumes you know how to declare and use pointers.

Reply With Quote
  #9  
Old November 11th, 2008, 02:27 PM
sizablegrin's Avatar
sizablegrin sizablegrin is offline
Dev Shed God 1st Plane (5500 - 5999 posts)
 
Join Date: Jun 2005
Posts: 5,964 sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level)sizablegrin User rank is General 58th Grade (Above 100000 Reputation Level) 
Time spent in forums: 2 Months 3 Weeks 2 Days 12 h 47 m 19 sec
Warnings Level: 10
Number of bans: 1
Reputation Power: 4851
See the link in my signature for a tutorial on pointers. It's not really difficult, just matter of perception and understanding.

There's also a good tut at eternallyconfuzzled.com.

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming LanguagesC Programming > Array initialization?

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap