Thread: Is there a standard function?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Jun 2010
    Posts
    182

    Question Is there a standard function?

    Hello everybody,

    I recently started studying C, and so far I didn't find a function to format
    integer numbers with thousand comma separators:

    30000000 value to format
    30,000,000 formatted value.

    Do you know if there is a standard function to do this kind of formatting?

    Thank you
    Last edited by frktons; 06-26-2010 at 06:53 AM.

  2. #2
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    There is no standard function to do that as far as I know but you can read here how to do it manually, although it may be a little too much to handle if you have just started learning the language.
    Question 12.11
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  3. #3
    Registered User
    Join Date
    Jun 2010
    Posts
    182

    Smile

    Quote Originally Posted by claudiu View Post
    There is no standard function to do that as far as I know but you can read here how to do it manually, although it may be a little too much to handle if you have just started learning the language.
    Question 12.11
    Thanks claudiu, I'll give it a look.
    If I cannot grasp the meaning, I'll try to build a function to do that.

  4. #4
    Registered User
    Join Date
    Jun 2010
    Posts
    182

    Question formatting numbers

    I tried to assemble a routine for the formatting task, but it looks like
    I missed something:
    Code:
    // ----------------------------------------------------------------------------------------------
    // Prog_name: comma_sep.c / ver 0.0
    // Date: 27 june 2010
    // Author: frktons @ cprogramming forum.
    //-----------------------------------------------------------------------------------------------
    // A routine for separating integer numbers with thousands comma separator. 
    // Created with Pelles C for Windows 6.00.4
    //-----------------------------------------------------------------------------------------------
    #include <stdio.h>
    #undef getchar
    #pragma comment(lib, "\\masm32\\lib\\msvcrt.lib")
    
    int main(int argc, char *argv[])
    {
        int num1 = 30000;
        int num2 = 50000;
        int result = (num1 * num2);
        int num = result;
        char buffer[14] = {' '};
        int len_str = 14;
        int x;
        int remain = 0;
        int count = 0;
        char digit[10] = {'0','1','2','3','4','5','6','7','8','9'};    
    
    
        printf("\nThe value of result is: %d\n",result);
    
        for (x = len_str; x > 0; x--)
          {
    	if (num == 0) 
              break;	
    
    	if (count == 3)
    	  {
    	    count = 0;
    	    buffer[x] = ',';
    	    x--;
    	  }
    
           remain = num % 10;
           num = num / 10;
           buffer[x] = digit[remain];
           count++;
        
          }  
    
        printf("\nThe formatted value of result is: %s\n",buffer);
        getchar();
        return 0;
    }
    What did I miss?

    Thanks
    Last edited by frktons; 06-26-2010 at 07:29 PM.

  5. #5
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    I don't know if you just prefer //s or something, but you may find /**/s helpful.

    What are you missing? What's wrong with the output?

  6. #6
    Registered User
    Join Date
    Jun 2010
    Posts
    182

    Unhappy

    Quote Originally Posted by User Name: View Post
    I don't know if you just prefer //s or something, but you may find /**/s helpful.

    What are you missing? What's wrong with the output?
    Well, // and /* */ are quite the same in C99, no problem with that.

    What's missing? the printf of the final string array doesn't show up.
    Code:
        printf("\nThe formatted value of result is: %s\n",buffer);
    Last edited by frktons; 06-26-2010 at 08:43 PM.

  7. #7
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by frktons View Post
    What did I miss?

    Thanks
    A C string is formally defined as a sequence of characters ending with and including zero. If you are going to fill a string backwards you have to take care to do it correctly:

    Code:
    int next , x;
    
    for (x = len_str - 1 , next = 0; x > -1 && next < len_str; x-- ) {
       ... determine grouping ...
    
       if (comma) {
          buffer[x - next] = ',';
          next++;
       }
    
       buffer[x - next] = digits[remain];
       next++;
    
       ... update num ...
       
       if (num == 0) {
          buffer[next] = '\0';
          break;
       }
    }
    No nudging of x should be necessary; let the loop count backward.

    While, in the program you wrote, result will never be negative, it is also impractical to think that always. You'll have to tweak it a bit for that.
    Last edited by whiteflags; 06-26-2010 at 08:53 PM.

  8. #8
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by whiteflags View Post
    A C string is formally defined as a sequence of characters ending with and including zero. If you are going to fill a string backwards you have to take care to do it correctly:

    Code:
    int next , x;
    
    for (x = len_str - 1 , next = 0; x > -1 && next < len_str; x-- ) {
       ... determine grouping ...
    
       if (comma) {
          buffer[x - next] = ',';
          next++;
       }
    
       buffer[x - next] = digits[remain];
       next++;
    
       ... update num ...
       
       if (num == 0) {
          buffer[next] = '\0';
          break;
       }
    }
    No nudging of x should be necessary; let the loop count backward.

    While, in the program you wrote, result will never be negative, it is also impractical to think that always. You'll have to tweak it a bit for that.
    Thanks whiteflags.

    I have to meditate for a while in order to understand the syntax of your code,
    in the meanwhile I came up with a crumpled working solution:
    Code:
    // ----------------------------------------------------------------------------------------------
    // Prog_name: comma_sep.c / ver 0.0
    // Date: 27 june 2010
    // Author: frktons @ cprogramming forum.
    //-----------------------------------------------------------------------------------------------
    // A routine for separating integer numbers with thousands comma separator. 
    // Created with Pelles C for Windows 6.00.4
    //-----------------------------------------------------------------------------------------------
    #include <stdio.h>
    #undef getchar
    #pragma comment(lib, "\\masm32\\lib\\msvcrt.lib")
    
    int main(int argc, char *argv[])
    {
        int num1 = 30000;
        int num2 = 50000;
        int result = (num1 * num2);
        int num = result;
        char buffer[14] = {' '};
        int len_str = 13;
        int x;
        int remain = 0;
        int count = 0;
        char digit[10] = {'0','1','2','3','4','5','6','7','8','9'};    
    
    
        printf("\nThe value of result is: %d\n",result);
    
        for (x = len_str; x > 0; x--)
          {
    	if (num == 0) 
              break;	
    
    	if (count == 3)
    	  {
    	    count = 0;
    	    buffer[x] = ',';
    	    x--;
    	  }
    
           remain = num % 10;
           num = num / 10;
           buffer[x] = digit[remain];
           count++;
        
          }  
    
        printf("\nThe formatted value of result is: ");
        for (x = 0; x < 14; x++)
    	printf("%c",buffer[x]);	 
        getchar();
        return 0;
    }
    And the output:
    Code:
    The value of result is: 1500000000
    
    The formatted value of result is:  1,500,000,000
    You are totally right about the number being always positive, and I'm
    going to complete the logic of the code, as soon as I know how to do it.

    This is only a simple exercise I'm doing in order to learn some C syntax, nothing
    more for the time being. :-)
    Last edited by frktons; 06-27-2010 at 07:57 PM.

  9. #9
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Actually, I'm lucky you're still here cause I made a mistake. Instead of using x, you should be using the len_str variable. We don't even need x:

    Code:
    int next;
    
    for (next = 0; next < len_str; ) {
       ... determine grouping ...
    
       if (comma) {
          buffer[len_str - next - 1] = ',';
          next++;
       }
    
       buffer[len_str - next - 1] = digits[remain];
       next++;
    
       ... update num ...
       
       if (num == 0) {
          buffer[next] = '\0';
          break;
       }
    }
    Sorry for the inconvenience.
    Last edited by whiteflags; 06-26-2010 at 09:22 PM.

  10. #10
    Registered User
    Join Date
    Jun 2010
    Posts
    182
    Quote Originally Posted by whiteflags View Post
    Actually, I'm lucky you're still here cause I made a mistake. Instead of using x, you should be using the len_str variable. We don't even need x:

    Code:
    int next;
    
    for (next = 0; next < len_str; ) {
       ... determine grouping ...
    
       if (comma) {
          buffer[len_str - next - 1] = ',';
          next++;
       }
    
       buffer[len_str - next - 1] = digits[remain];
       next++;
    
       ... update num ...
       
       if (num == 0) {
          buffer[next] = '\0';
          break;
       }
    }
    Sorry for the inconvenience.
    Thanks again.

    I'm not going anywhere, I've just arrived here and I hope I'll stay for a while. :-)

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    >>#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.
    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.

  12. #12
    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.

  13. #13
    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.

  14. #14
    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.

  15. #15
    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.

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