Thread: Is there a standard function?

  1. #16
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by Elysia View Post
    >>#undef getchar
    getchar is a function, not a macro. Therefore, you cannot undefine it. The line is pointless.

    >>#pragma comment(lib, "\\masm32\\lib\\msvcrt.lib")
    This is implicit. The linker will always link to the standard C runtime library by default. It should be safe to remove this.
    I'm using Pelles C, as you can see in the comments I put at the beginning of the pgm.

    getchar is defined as a macro in Pelles C, and tends to give problems, so better not to use that.

    the #pragma directive points to the old msvcrt.lib [not to the standard new one] for downsizing
    the EXE.

    :-)

    Quote Originally Posted by Bayint Naung View Post
    But some compilers have macro and function versions
    So undef line is not necessarily pointless.
    Eg
    IBM...
    MSDN
    Edit: sorry about double post. Internet's slow here... ;(
    This is the case :-)

    Quote Originally Posted by whiteflags View Post
    I'm hoping ALL of the weird stuff is actually default project "junk".
    I'm afraid this is not the case. :-(
    Last edited by frktons; 06-27-2010 at 03:29 AM.

  2. #17
    Registered User
    Join Date
    Jun 2010
    Posts
    182

    Smile Formatting numbers

    I added some extra code to this version in order to check for negative or positive
    numbers, and to choose the separator.

    Any improvement you can suggest?

    Code:
    // ----------------------------------------------------------------------------------------------
    // Prog_name: comma_sep.c / ver 0.1
    // This version takes into account the sign and the possibility to have different
    //  separator like space, comma, point, and so on. 
    // Date: 27 june 2010
    // Author: frktons @ cprogramming forum.
    //-----------------------------------------------------------------------------------------------
    // A routine for separating integer numbers with thousands separator. 
    // Created with Pelles C for Windows 6.00.4
    //-----------------------------------------------------------------------------------------------
    #include <stdio.h>
    #include <stdbool.h>
    #undef getchar
    #pragma comment(lib, "\\masm32\\lib\\msvcrt.lib")
    
    int main(int argc, char *argv[])
    {
        bool sign = true;              // if the number has to be displayed with sign
        bool neg = false;             // if the number is negative
        bool zero = false;
        char sep = ',';                   // here I choose the separator
        int num = -12715;             // test number
    
        char buffer[15] = {' '};        // string array for the formatted number
        int len_str = 14;                 // string lenght less the terminator NULL
        int x;                                  // generic integer counters
        int remain = 0;                  // integer variable to store the remainder
        int count = 0;                    // integer counter for positioning the separator  
        char digit[10] = {'0','1','2','3','4','5','6','7','8','9'};   // the digit to display in char shape  
    
    
        printf("\n The value of result is: %d\n",num);
    
        if (num == 0) 
           {
    	   buffer[len_str] = '0';
    	   zero = true;
               goto pgm_end;	
           }
    
        if (num < 0)
          {
    	 neg = true;
             num = num * -1 ; // transform number to positive if negative
          }
        for (x = len_str; x >= 0; x--)
          {
    	if (num == 0) 
             break;
    
    	if (count == 3)
    	  {
    	    count = 0;
    	    buffer[x] = sep;
    	    x--;
    	  }
    
           remain = num % 10;
           num = num / 10;
           buffer[x] = digit[remain];
           count++;
        
          }  
    
    pgm_end: 
    
        if (sign == true && neg == true)
           buffer[x] = '-';
        else if (sign == true && zero == false)
    	buffer[x] = '+';
    //  end if
    
        printf("\n The formatted value of result is: ");
        for (x = 0; x < 15; x++)
           {
    	if (buffer[x] == '+' || buffer[x] == '-' || buffer[x] == sep || buffer[x] >= '0' && buffer[x] <= '9')
    	   printf("%c",buffer[x]);	
           }
        getchar();
        return 0;
    }
    And the output:

    Code:
     The value of result is: -12715
    
     The formatted value of result is: -12,715
    Enjoy
    Last edited by frktons; 06-27-2010 at 07:13 AM.

  3. #18
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    The most glaring problem is goto. You need to get rid of it. Use loops instead.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #19
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by Elysia View Post
    The most glaring problem is goto. You need to get rid of it. Use loops instead.
    It looks clear in this way, before entering any loop, to check if the value is zero and skipping
    the whole routine at once.

    The GOTO sin is not so unforgiveable after all. Let me do it at least once ;-)

    If you have a better idea, show me your code and I'll think about it and
    I'll enjoy more as well. :-)

  5. #20
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
    // ----------------------------------------------------------------------------------------------
    // Prog_name: comma_sep.c / ver 0.1
    // This version takes into account the sign and the possibility to have different
    //  separator like space, comma, point, and so on. 
    // Date: 27 june 2010
    // Author: frktons @ cprogramming forum.
    //-----------------------------------------------------------------------------------------------
    // A routine for separating integer numbers with thousands separator. 
    // Created with Pelles C for Windows 6.00.4
    //-----------------------------------------------------------------------------------------------
    #include <stdio.h>
    #include <stdbool.h>
    #undef getchar
    #pragma comment(lib, "\\masm32\\lib\\msvcrt.lib")
    
    int main(int argc, char *argv[])
    {
        bool sign = true;              // if the number has to be displayed with sign
        bool neg = false;             // if the number is negative
        bool zero = false;
        char sep = ',';                   // here I choose the separator
        int num = -12715;             // test number
    
        char buffer[15] = {' '};        // string array for the formatted number
        int len_str = 14;                 // string lenght less the terminator NULL
        int x;                                  // generic integer counters
        int remain = 0;                  // integer variable to store the remainder
        int count = 0;                    // integer counter for positioning the separator  
        char digit[10] = {'0','1','2','3','4','5','6','7','8','9'};   // the digit to display in char shape  
    
    
        printf("\n The value of result is: %d\n",num);
    
        if (num != 0) 
        {
            if (num < 0)
            {
                neg = true;
                num = num * -1 ; // transform number to positive if negative
            }
            for (x = len_str; x >= 0; x--)
           {
                if (num == 0) 
                    break;
                if (count == 3)
    	   {
    	       count = 0;
    	       buffer[x] = sep;
    	       x--;
                }
    
                remain = num % 10;
                num = num / 10;
                buffer[x] = digit[remain];
                count++;
            }  
        }
        else
        {
            buffer[len_str] = '0';
            zero = true;
        }
    
        if (sign == true && neg == true)
            buffer[x] = '-';
        else if (sign == true && zero == false)
            buffer[x] = '+';
    
        printf("\n The formatted value of result is: ");
        for (x = 0; x < 15; x++)
        {
            if (buffer[x] == '+' || buffer[x] == '-' || buffer[x] == sep || buffer[x] >= '0' && buffer[x] <= '9')
            printf("%c",buffer[x]);	
        }
        return 0;
    }
    Apologies if the indentation is poor in places. I don't have an editor to properly do it here.
    This gets rid of goto. Difficult, wasn't it?
    It's best not to rely on goto at all, since it's a good training to make proper logic using loops instead.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #21
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by Elysia View Post
    Code:
    // ----------------------------------------------------------------------------------------------
    // Prog_name: comma_sep.c / ver 0.1
    // This version takes into account the sign and the possibility to have different
    //  separator like space, comma, point, and so on. 
    // Date: 27 june 2010
    // Author: frktons @ cprogramming forum.
    //-----------------------------------------------------------------------------------------------
    // A routine for separating integer numbers with thousands separator. 
    // Created with Pelles C for Windows 6.00.4
    //-----------------------------------------------------------------------------------------------
    #include <stdio.h>
    #include <stdbool.h>
    #undef getchar
    #pragma comment(lib, "\\masm32\\lib\\msvcrt.lib")
    
    int main(int argc, char *argv[])
    {
        bool sign = true;              // if the number has to be displayed with sign
        bool neg = false;             // if the number is negative
        bool zero = false;
        char sep = ',';                   // here I choose the separator
        int num = -12715;             // test number
    
        char buffer[15] = {' '};        // string array for the formatted number
        int len_str = 14;                 // string lenght less the terminator NULL
        int x;                                  // generic integer counters
        int remain = 0;                  // integer variable to store the remainder
        int count = 0;                    // integer counter for positioning the separator  
        char digit[10] = {'0','1','2','3','4','5','6','7','8','9'};   // the digit to display in char shape  
    
    
        printf("\n The value of result is: %d\n",num);
    
        if (num != 0) 
        {
            if (num < 0)
            {
                neg = true;
                num = num * -1 ; // transform number to positive if negative
            }
            for (x = len_str; x >= 0; x--)
           {
                if (num == 0) 
                    break;
                if (count == 3)
    	   {
    	       count = 0;
    	       buffer[x] = sep;
    	       x--;
                }
    
                remain = num % 10;
                num = num / 10;
                buffer[x] = digit[remain];
                count++;
            }  
        }
        else
        {
            buffer[len_str] = '0';
            zero = true;
        }
    
        if (sign == true && neg == true)
            buffer[x] = '-';
        else if (sign == true && zero == false)
            buffer[x] = '+';
    
        printf("\n The formatted value of result is: ");
        for (x = 0; x < 15; x++)
        {
            if (buffer[x] == '+' || buffer[x] == '-' || buffer[x] == sep || buffer[x] >= '0' && buffer[x] <= '9')
            printf("%c",buffer[x]);	
        }
        return 0;
    }
    Apologies if the indentation is poor in places. I don't have an editor to properly do it here.
    This gets rid of goto. Difficult, wasn't it?
    It's best not to rely on goto at all, since it's a good training to make proper logic using loops instead.
    Good!!! I like it. I have to say that not only you got rid of GOTO but of
    getchar() as well :-)

    This example is one the many to come before this routine will be ready.
    Just a toy to learn some C syntax. And after all I wonder why after more than 30 years
    no standard C function does this work.
    Last edited by frktons; 06-27-2010 at 07:44 AM.

  7. #22
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I got rid of getchar because it was at the end of the main function. It is usually used to pause the console, but not in a good way. This article describes some ways, the ones near the top being the best alternatives: SourceForge.net: Pause console - cpwiki

    Regarding the function, probably because the standard committee had more important things to spend their time on. They have a limited time and a lot of things to do. And there are probably libraries to do this sort of stuff. And I guess the usage is not near enough to demand the need to implement this stuff.
    Most financial applications aren't done in C. They're done in high-level languages that are very secure.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #23
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by Elysia View Post
    I got rid of getchar because it was at the end of the main function. It is usually used to pause the console, but not in a good way. This article describes some ways, the ones near the top being the best alternatives: SourceForge.net: Pause console - cpwiki

    Regarding the function, probably because the standard committee had more important things to spend their time on. They have a limited time and a lot of things to do. And there are probably libraries to do this sort of stuff. And I guess the usage is not near enough to demand the need to implement this stuff.
    Most financial applications aren't done in C. They're done in high-level languages that are very secure.
    I agree with you. About the alternatives to getchar() I think I'll wait until the Windows APIs
    will show me something better to do, if any exists at all. All the possible ways to halt the console
    waiting for a key press are not what I really need, to do some serious coding, but fortunately it'll
    be not very soon in the near future. :-)

  9. #24
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    What, exactly, do you need to do?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #25
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by Elysia View Post
    What, exactly, do you need to do?
    Scan the keystrokes one at a time, without having them displayed on the screen,
    checking them, deciding if they are worth considering for the input field, and then
    display them at a row,col position, with selected attributes, filling an input variable
    with the bytes after validation, and so on.

    I mean a [simple] input/output routine like the ones we used in DOS age, but with the
    win32 console features.

    As far as I know only Windows API will give me the fine control I need over the steps that
    I briefly mentioned.

    Before going into that, I think it's better to know some basic-intermediate C syntax, and
    this is the reason I started studying it some weeks ago.

    Of course the input/output routine is just one of the million steps forward. :-)

    I selected it for the variety of thinks needed to accomplish the task. A good and maybe
    useful exercise. Who knows, I can even use the routine when it is finished. ;-)

    Displaying numbers with a thousands separator is a tiny part of the whole.
    Last edited by frktons; 06-27-2010 at 07:48 PM.

  11. #26
    Registered User
    Join Date
    Jun 2010
    Posts
    182

    Smile Formatting integer numbers

    After a little experimentation, I came out with this 0.3 release that
    is a major step towards the definitive version, next co come :-)
    In this version the code for formatting is inside a function, and it is tested
    for performance as well.

    On my pc Core duo Intel it takes about 12 seconds to perform 100 million
    formatting of a long integer, with sign and thousand separator.

    I'd like some comment on possible improvement both in style, and in performance
    if anybody would be so kind to point out some deficiency or better coding.

    Thanks

    Code:
    // ----------------------------------------------------------------------------------------------
    // Prog_name: comma_sep.c / ver 0.3
    // A routine for separating integer numbers with thousands separator. 
    // Created with Pelles C for Windows 6.00.4
    //-----------------------------------------------------------------------------------------------
    // This version takes into account the sign and the possibility to have different
    // separator like space, comma, point, and so on. 
    // Moveover this version creates a function that can be tested for performance. 
    //-----------------------------------------------------------------------------------------------
    // Date: 03 july 2010
    // Author: frktons @ cprogramming forum.
    //-----------------------------------------------------------------------------------------------
    
    #include <stdio.h>
    #include <stdbool.h>
    #include <time.h>
    #undef getchar
    #pragma comment(lib, "\\masm32\\lib\\msvcrt.lib")
    
    //-----------------------------------------------------------------------------------------------
    // Global variables. In future versions will go into an header file
    //-----------------------------------------------------------------------------------------------
        bool sign = true;              // if the number has to be displayed with sign
        bool neg = false;              // if the number is negative this flag will be set
                                                  // from the function to reflect the state
        bool zero = false;             // if the number is zero the function sets this
                                                  // flag for its decisions
        char sep = ',';                   // here I choose the separator 
        char buffer[15] = {' '};        // string array for the formatted number
    
    //-----------------------------------------------------------------------------------------------
    // Function prototype for int_format(). Takes the number to format
    // and the address of the string to fill. Returns nothing.
    //-----------------------------------------------------------------------------------------------
    
    void int_format(int num);
    
    //-----------------------------------------------------------------------------------------------
    
    int main(int argc, char *argv[])
    {
     
        int num = -1234567153;   // test number to format
        int cycles = 0;
    
    
        int x;                                  // generic integer counter
        time_t init_time = 0;          // initial time
        time_t end_time = 0;        // end time 
     
        int times = 100000000;               // for testing performance set this number for repetitions
    
    
        printf("\n The value of num is: %d\n",num);
    
        time(&init_time);
    
    
        printf("\n init_time =%d\n",init_time);    
    
        for (cycles = 0; cycles < times; cycles++) {
            int_format(num);
            for (x=0; x < 15; x++)
                buffer[x] = ' '; 
        } // end for
        int_format(num);
        printf("\n The formatted value of result is: ");
        for (x = 0; x < 15; x++)
        {
            if (buffer[x] == '+' || buffer[x] == '-' || buffer[x] == sep || buffer[x] >= '0' && buffer[x] <= '9')
            printf("%c",buffer[x]);	
        }
        printf("\n");
        time(&end_time);
        printf(" end_time =%d\n",end_time);    
    
        printf("\n\n The routine has taken about %d seconds\n", end_time - init_time);
        getchar();
        return 0;
    }
    //--------------------------------------------------------------------------------------------------------------------
    // Function int_format()
    //--------------------------------------------------------------------------------------------------------------------
    
    void   int_format(int num){
    
        int x = 0;
        int remain = 0;                  // integer variable to store the remainder
        int count = 0;                    // integer counter for positioning the separator  
        char digit[10] = {'0','1','2','3','4','5','6','7','8','9'};   // the digits to display in char shape 
        int len_str = 14;                 // string lenght less the terminator NULL
    
        if (num != 0) 
        {
            if (num < 0)
            {
                neg = true;
                num = num * -1 ; // transform number to positive if negative
            }
            for (x = len_str; x >= 0; x--)
             {
                if (num == 0) 
                    break;
                if (count == 3)
    	   {
    	       count = 0;
    	       buffer[x] = sep;
    	       x--;
                }
    
                remain = num % 10;
                num = num / 10;
                buffer[x] = digit[remain];
                count++;
              }  
        }
        else
        {
            buffer[len_str] = '0';
            zero = true;
        }
    
        if (sign == true && neg == true)
            buffer[x] = '-';
        else if (sign == true && zero == false)
            buffer[x] = '+';
    
        return;
    
    }
    Last edited by frktons; 07-03-2010 at 07:57 AM.

  12. #27
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by frktons
    I'd like some comment on possible improvement both in style, and in performance
    if anybody would be so kind to point out some deficiency or better coding.
    Is there any reason that you are using global variables for values that are specific to each call of the int_format function? They should be local variables instead; some of them should be function parameters.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #28
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by laserlight View Post
    Is there any reason that you are using global variables for values that are specific to each call of the int_format function? They should be local variables instead; some of them should be function parameters.
    They will be part of a header file, so I was thinking about the scope of the
    variables, and I decided to set them as Global.
    Maybe I'm wrong, but I think variables in header are Global.

  14. #29
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    It sounds like you have the reasoning backwards. If you decide that the variable should be global, then you would likely place an extern declaration of that variable in a header. But if you started by deciding that "they will be part of a header file"... what motivated that decision?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #30
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by laserlight View Post
    It sounds like you have the reasoning backwards. If you decide that the variable should be global, then you would likely place an extern declaration of that variable in a header. But if you started by deciding that "they will be part of a header file"... what motivated that decision?
    I've taken into account the fact that this is an evolving function that
    will be ready some weeks forward in the future. The final idea is that I'll use a structure
    with these variables, and the prototype of the function, and all of them
    will be in a header.

    The function will be called with a pointer to the structure.

    I'm reasoning this way because I'm learning C syntax but I already have in
    my mind what I want. So while I develop the function, I learn the syntax
    and implement new versions of the same function.

    It's a kind of exercise to put into practice what I learn. :-)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Change this program so it uses function??
    By stormfront in forum C Programming
    Replies: 8
    Last Post: 11-01-2005, 08:55 AM
  3. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM
  4. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM
  5. Replies: 5
    Last Post: 02-08-2003, 07:42 PM