Thread: The time has come...

  1. #1
    Registered User
    Join Date
    Jan 2005
    Posts
    5

    The time has come...

    First of all id like to thank cprogramming.com and its member's for its fantastic tutorials and faq's as between you guy's and google you've taught me all i know about c/c++

    ive been to writing a simple program to control a parallel port I/O card, but the time has come where i need a little help.

    the code snip below is what im using to check the variable "input" against the input_address array, this works fine for checking 1 input line at a time but if 2 or more inputs are pulled high it dosent work.

    let say input 1 and 2 are high the variable "input" will = 3
    or if all 8 are high "input" will = 255
    i need it to print out, inputs 1 and 2 are high or inputs 1, 2, 3, 4, 5, 6, 7 and 8 are high and whatever in between e.g.,

    if the variable "input" == 82 then print inputs 2, 5 and 7 are high

    Code:
    int input_adress[10] = {0,1,2,4,8,16,32,64,128};
    
    for (i = 1;i < 9;i++)
      { if (input == input_adress[i])
        {
          cout << "Input " << i << " is HIGH" << endl; }
        else 
        { input == 0;
         cout << "Input " << i << " in LOW" << endl; }}
    and for my second question, in the line below how do i put these : every 2 digits to get the output to look like this 12:01:01 instead of 120101

    Code:
    cout << "The time is"<< setfill('0') << setw(6) << thetime << endl;
    Thank you for your very much time Budgie

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    That's somewhat of a tricky formatting scheme. If you do it with straight printing, it would end up looking like this:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      int input_address[10] = {0,1,2,4,8,16,32,64,128};
      int input = 4;
      bool high = false;
    
      for (int i = 1; i < 9; i++)
      {
        if (input > input_address[i])
        {
          high = true;
    
          // Not the first item
          if (i != 1) {
            if (i == 8 || (i + 1 < 9 && input == input_address[i + 1]))
              cout << " and ";
            else
              cout << ", ";
          }
          cout << i;
        }
      }
      if (!high)
        cout << "No items";
      cout << " are high" << endl;
    }
    Not very pretty. A better way is to save the high values and then pretty print them after the processing is done:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      int input_address[10] = {0,1,2,4,8,16,32,64,128};
      int high[8] = {0};
      int n = 0;
      int input = 4;
    
      for (int i = 1; i < 9; i++)
      {
        if (input > input_address[i])
          high[n++] = i;
      }
      
      if (n == 0)
      {
        cout << "No items are high" << endl;
      }
      else {
        cout << (n == 1 ? "Input " : "Inputs ");
        for (int i = 0; i < n; i++)
        {
          cout << high[i];
          if (i + 1 == n - 1)
            cout << " and ";
          else if (i != n - 1)
            cout << ", ";
        }
        cout << (n == 1 ? " is " : " are ") << "high" << endl;
      }
    }
    It might not be as concise, but it's easier to get right, and localizing/separating operations will greatly simplify your code. The nice part is that now you can modularize the pretty print into a function:
    Code:
    #include <iostream>
    
    using namespace std;
    
    void print(int high[], int n)
    {
      if (n == 0)
      {
        cout << "No items are high" << endl;
      }
      else {
        cout << (n == 1 ? "Input " : "Inputs ");
        for (int i = 0; i < n; i++)
        {
          cout << high[i];
          if (i + 1 == n - 1)
            cout << " and ";
          else if (i != n - 1)
            cout << ", ";
        }
        cout << (n == 1 ? " is " : " are ") << "high" << endl;
      }
    }
    
    int main()
    {
      int input_address[10] = {0,1,2,4,8,16,32,64,128};
      int high[8] = {0};
      int n = 0;
      int input = 4;
    
      for (int i = 1; i < 9; i++)
      {
        if (input > input_address[i])
          high[n++] = i;
      }
    
      print(high, n);
    }
    >every 2 digits to get the output to look like this 12:01:01 instead of 120101
    Is thetime and integer or a string? If it's a string then the task is a simple matter of printing two characters then a colon:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      char thetime[] = "120101";
    
      cout << "The time is "
        << thetime[0] << thetime[1] << ':'
        << thetime[2] << thetime[3] << ':'
        << &thetime[4] << endl;
    }
    C++ strings make it much cleaner:
    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
      string thetime = "120101";
    
      cout << "The time is "
        << thetime.substr(0, 2) << ':'
        << thetime.substr(2, 2) << ':'
        << thetime.substr(4) << endl;
    }
    Though if you're using strings, you should have formatted them correctly to begin with, so I suspect you're using an integer. That's harder, but because times are well formatted, you can do something like this:
    Code:
    #include <iomanip>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      int thetime = 120101;
    
      cout << "The time is "
        << setw(2) << setfill('0') << thetime / 10000 << ':'
        << setw(2) << setfill('0') << (thetime / 100) % 10 << ':'
        << setw(2) << setfill('0') << thetime % 10 << endl;
    }
    Too bad it's not a good one-liner.
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    5
    wow thanks for the fast replys, its gunna take me a bit to get my head around this, i'll get back to you guy's soon as i do

    For the second question: what is the exact nature of the variable "thetime"?

    If its value is decimal 120101, does this indicate one second past one minute past noon, or what? (Is this on a 24-hour clock?)
    yeah it does indicate one second past one minute past noon

    its an integer of a 24 hour clock

    Thanks for your time, budgie

  4. #4
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    wow thanks for the fast replys
    55 minutes is a slow response time here, actually. But not for THAT kind of response.

  5. #5
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote Originally Posted by Prelude
    Though if you're using strings, you should have formatted them correctly to begin with, so I suspect you're using an integer. That's harder, but because times are well formatted, you can do something like this:
    Code:
    #include <iomanip>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
      int thetime = 120101;
    
      cout << "The time is "
        << setw(2) << setfill('0') << thetime / 10000 << ':'
        << setw(2) << setfill('0') << (thetime / 100) % 10 << ':'
        << setw(2) << setfill('0') << thetime % 10 << endl;
    }
    Not quite (try it with thetime =123456).

    You could do this:

    Code:
        hours = thetime/10000;
        minutes = (thetime - hours*10000)/100;
        seconds = thetime - hours*10000 - minutes*100;
    Regards,

    Dave
    Last edited by Dave Evans; 01-09-2005 at 10:22 AM.

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Not quite (try it with thetime =123456).
    Oops, my 10's should have been 100's. Serves me right for not compiling and testing my own example.
    My best code is written with the delete key.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    5
    Thank's guys the time formating work's well
    i wrote a small program to test the input stuff, its close but dosent retern the right values

    Code:
    #include <iostream>
    #include <sys/io.h>
    
    using namespace std;
    
    #define PORTADDRESS 0x378  		 // Parallel port address
    #define DATA PORTADDRESS	         // DATA address
    #define STATUS PORTADDRESS+1	         // STATUS address
    #define CONTROL PORTADDRESS+2		 // CONTROL address
    
    int main()
    {
      int card_on, input, i;
      int input_address[10] = {0,1,2,4,8,16,32,64,128};
      int cards[10] = {0,10,8,14,12,2,0,6,4};
      int low[8] = {0};
      int n = 0;
      //int input = 4; took this out
    
      cout <<"Select what card to use ( 1-8 ) :> ";
      cin >> card_on;
      cout << "Using Card Number " << card_on << endl ;
    
      if (ioperm(PORTADDRESS,3,1)) {perror("ioperm");exit(1);} // Open the parllel port
    
      outb(cards[card_on], CONTROL);    // Select card
      outb(cards[card_on]+1, CONTROL);  // Latch data
    
      for(i = 1; i <= 128; i++)
      {
        outb(120, STATUS);            
        outb(5, CONTROL);          
      }
      input = (inb(STATUS) & 248) ^ 120;            
      input =  input | ((inb(CONTROL) & 14) ^ 4) / 2;  
      outb(cards[card_on], CONTROL);                 
      cout << "the input value is "<< input << endl;
    
      // your example
      for (int i = 1; i < 9; i++)
      {
        if (input > input_address[i])
          low[n++] = i;
      }
    
      if (n == 0)
      {
        cout << "No items are low" << endl;
      }
      else
      {
        cout << (n == 1 ? "Input " : "Inputs ");
        for (int i = 0; i < n; i++)
        {
          cout << low[i];
          if (i + 1 == n - 1)
            cout << " and ";
          else if (i != n - 1)
            cout << ", ";
        }
        cout << (n == 1 ? " is " : " are ") << "low" << endl;
      }
      // end example
    
    if (ioperm(PORTADDRESS,3,0)) {perror("ioperm");exit(1);}  // Close the parllel port
    
      exit(0);
    }
    here's the output, the first one is working input = 0, all inputs are high (had my highs and lows the wrong way around in my fist post)
    the second one input value = 4 should be input 3 is low
    the third value = 254 should be inputs 2,3,4,5,6,7 and 8 are low

    Code:
    [root@home src]# ./jaycar_testbed
    Select what card to use ( 1-8 ) :> 1
    Using Card Number 1
    input value is 0
    No items are low
    
    [root@home src]# ./jaycar_testbed
    Select what card to use ( 1-8 ) :> 1
    Using Card Number 1
    input value is 4
    Inputs 1 and 2 are low
    
    [root@home src]# ./jaycar_testbed
    Select what card to use ( 1-8 ) :> 1
    Using Card Number 1
    input value is 254
    Inputs 1, 2, 3, 4, 5, 6, 7 and 8 are low
    [root@home src]#
    i did take this out "int input = 4;" and replaced it with the integer reterned from the I/O card is this the prob.

    once again thanks for your time

  8. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    You're making less sense now.

    >the second one input value = 4 should be input 3 is low
    Okay, but what about 1 and 2? And item 3 is 4, which is equal to input. Is that considered high or low?

    >the third value = 254 should be inputs 2,3,4,5,6,7 and 8 are low
    What about 1? I don't see a pattern in these new results, and it looks like you want something completely different from what you asked for previously.
    My best code is written with the delete key.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    5
    sorry im not to good at explaning things, i'll try again

    the variable "input" is going to be a number somewhere between 0 and 255 depending on what state the card inputs r in.

    so if the input == 254 in binary it = 11111110

    76543210
    . . . . . . . . 1
    . . . . . . * . 2
    . . . . . * . . 4
    . . . . * . . . 8
    . . . * . . . . 16
    . . * . . . . . 32
    . * . . . . . . 64
    * . . . . . . . 128

    so 2 + 4 + 8 +16 +32 + 64 + 128 = 254 so inputs 2,3,4,5,6,7,and 8 are low

    so if the input == 48 in binary it = 00110000

    76543210
    . . . . . . . . 1
    . . . . . . . . 2
    . . . . . . . . 4
    . . . . . . . . 8
    . . . * . . . . 16
    . . * . . . . . 32
    . . . . . . . . 64
    . . . . . . . . 128

    16 + 32 = 48 inputs 5 and 6 are low

    can you see what i mean, i should realy number the inputs 0-7 not 1-8

  10. #10
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote Originally Posted by budgie
    sorry im not to good at explaning things, i'll try again

    the variable "input" is going to be a number somewhere between 0 and 255 depending on what state the card inputs r in.

    so if the input == 254 in binary it = 11111110

    76543210
    . . . . . . . . 1
    . . . . . . * . 2
    . . . . . * . . 4
    . . . . * . . . 8
    . . . * . . . . 16
    . . * . . . . . 32
    . * . . . . . . 64
    * . . . . . . . 128

    so 2 + 4 + 8 +16 +32 + 64 + 128 = 254 so inputs 2,3,4,5,6,7,and 8 are low

    so if the input == 48 in binary it = 00110000

    76543210
    . . . . . . . . 1
    . . . . . . . . 2
    . . . . . . . . 4
    . . . . . . . . 8
    . . . * . . . . 16
    . . * . . . . . 32
    . . . . . . . . 64
    . . . . . . . . 128

    16 + 32 = 48 inputs 5 and 6 are low

    can you see what i mean, i should realy number the inputs 0-7 not 1-8

    The way that you are testing the bits is fundamentally wrong.

    Why not use a bit mask?

    Test this with whatever inputs you want to try, then if it looks OK, you can integrate it into your program to get the output formatted as required.

    Code:
    #include <iostream>
    using namespace std;
    
    int main()
    {
      int input;
      int mask;
      int i;
    
      while (1) {
        cout << "Enter a number: " << flush;
        cin >> input;
        if (!cin) {
          break;
        }
        cout << "You entered " << input << endl;
    
        mask = 1; // start '1' in lsb
        for (i = 0; i < 8; i++) // number lsb = 0, msb = 7
        {
          if ((input & mask)) { // check for '1'
            cout << "  bit " << i << " is high" << endl;
          }
          mask <<= 1;
        }
        cout << endl;
      }
      return 0;
    }
    Regards,

    Dave
    Last edited by Dave Evans; 01-09-2005 at 02:03 PM.

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    5
    you the man Dave, thank you very much, that's what i need.

    Prelude thanks for your help m8, sorry about confusion

    all the best, budgie

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to get current time
    By tsubasa in forum C Programming
    Replies: 3
    Last Post: 05-01-2009, 02:03 AM
  2. Replies: 11
    Last Post: 03-29-2009, 12:27 PM
  3. Help with assignment!
    By RVDFan85 in forum C++ Programming
    Replies: 12
    Last Post: 12-03-2006, 12:46 AM
  4. calculating user time and time elapsed
    By Neildadon in forum C++ Programming
    Replies: 0
    Last Post: 02-10-2003, 06:00 PM
  5. time class
    By Unregistered in forum C++ Programming
    Replies: 1
    Last Post: 12-11-2001, 10:12 PM