Thread: Simple unit converter

  1. #1
    Registered User
    Join Date
    Apr 2017
    Posts
    4

    Simple unit converter

    Hello,

    I am quite new at C programming, however I wanted to create simple volt and ampere unit converter. Volt converter is working fine but without new created function called int converter_ask(); I wanted to have a choice at the beginning of program and to chose converter which I want. It seems that scanf function is holding in memory what I choose (number 1) and program is not running correctly. I tried with different options like getchar, gets etc but none of them are working.

    Any ideas how I may solve this?

    Many thanks for support and effort.
    Best,
    Tom

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
    
    char con_type;
    int unit; //unit of measurement
    double amt,x_mv,x_v; //amount of volts depends of uom
    double mv_1 = 0.001;
    double v_1 = 0.000001;
    double mv_2 = 1000;
    double v_2 = 0.001;
    double mv_3 = 1000;
    double v_3 = 1000000;
    
    
    int main()
    {
        //Variable setup
    
        intro();
        converter_ask();
        //volt_conversion();
        return 0;
    
    }
    
    int intro()
    
    {
        printf("***Welcome in volt unit converter***\n");
        printf("\t   ver. 0.2\n");
        printf("--------------------------------------\n\n");
    }
    
    int converter_ask()
    
    {
        printf("Please specify the converter type\n");
        printf("1 - Volt / 2 - Ampere\n");
        con_type = gets();
        switch(con_type){
        case '1':
        volt_conversion();
        break;
    
        }
    }
    
    int volt_conversion()
    
    {
        printf("Please specify unit of measurement:\n");
        printf("1 - microVolt / 2 - miliVolt / 3 - Volt\n ");
        unit = getchar();
        printf("Please provide amount of volts in chosen unit:\n");
        scanf("%lf", &amt);
    
        switch(unit){
            case '1':
            x_mv = amt * mv_1;
            x_v = amt * v_1;
            if(amt!=0){
            printf("%lf uV is equal to: %lf mV \n",amt,x_mv);
            printf("%lf uV is equal to: %lf V \n",amt,x_v);
            }
            else if(amt==0){
                printf("You are multiplying by 0! It is not allowed!\n");
            }
            break;
            case '2':
            x_mv = amt * mv_2;
            x_v = amt * v_2;
            if(amt!=0){
            printf("%lf mV is equal to: %lf uV \n",amt,x_mv);
            printf("%lf mV is equal to: %lf V \n",amt,x_v);
            }
            else if(amt==0){
                printf("You are multiplying by 0! It is not allowed!\n");
            }
            break;
            case '3':
            x_mv = amt * mv_3;
            x_v = amt * v_3;
            if(amt!=0){
            printf("%lf V is equal to: %lf mV \n",amt,x_mv);
            printf("%lf V is equal to: %lf uV \n",amt,x_v);
            }
            else if(amt==0){
                printf("You are multiplying by 0! It is not allowed!\n");
            }
            break;
        }
    }

  2. #2
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    733
    You need to do some cleanup first.

    Don't use global data! Move them to main() and pass them by value or address to whatever function needed.

    gets() has been depreciated in C99, and is no longer in the Standard Library in C11!

    Turn on and turn up the warning level in your compiler!

    Start here and repost your updated code.

  3. #3
    Registered User
    Join Date
    Feb 2012
    Posts
    347
    Why cannot you use scanf at all the places? Any specific reason ?

  4. #4
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    733
    I didn't look closely enough at your code before I responded. Sorry!
    Code:
    con_type = gets();
    This is completely wrong.
    gets() takes a char array as the argument, and returns either a pointer to the char array is successfully, or NULL if it failed, or no characters were read. gets() has been depreciated in C99, and removed from C11. fgets() should be used instead of gets() no matter what Standard you are using for most String input.

    Yes, you could use scanf() for all input in this program. My other recommendations still hold true.

    Better formatting of the code is also recommended. Please see this article on Indent Style.
    Last edited by rstanley; 04-20-2017 at 08:23 PM.

  5. #5
    Registered User
    Join Date
    Apr 2017
    Posts
    4

    Thumbs up

    Good evening,

    I've managed to find some time and clean the code a bit.

    1) Also I added "intends", maybe not in professional way but it should be more "readable" now.
    2)I know that gets() is no longer in use- I was just playing with it. Was curious if get any decent output from it.
    3)The problem exist when I want to implement 2nd converter. To do this I want to ask question about converter type. The whole issue is that when I am responding on 1st question regarding converter type the code omits 2nd question, goes straight to 3rd one (amount of volts) and even if I put anything the code stops. It seems like the answer from 1st question was stored in memory and other scanf's won't work.
    4) Ok I have modified code and now I am getting what I wanted, however it seems that my if statement is not working correctly. If i type "volt" script is going correctly, however if I type amp it still goes same way as volt converter. It seems like that if was not read at all.


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>
    
    int main()
    {
    
    //Variable setup
    char myreply[10];
    int unit; //unit of measurement
    double amt,x_mv,x_v; //amount of volts depends of unit of measurement
    //-------------------------------------------------------------------
    //Constant values for unit conversion
    double mv_1 = 0.001;
    double v_1 = 0.000001;
    double mv_2 = 1000;
    double v_2 = 0.001;
    double mv_3 = 1000;
    double v_3 = 1000000;
    //-------------------------------------------------------------------
    
    //Initiate intro information window
    intro();
    
    printf("Please chose type of converter:\n");
    printf("volt - Volt converter / amp - Ampere converter\n");
        fgets(myreply,sizeof(myreply),stdin);
    
    //!! IF IS NOT READ CORRECTLY
        if(strcmp(myreply,"volt")){
    
    
    
    printf("Please specify unit of measurement:\n");
    printf("1 - microVolt / 2 - miliVolt / 3 - Volt\n ");
        unit = getchar();
    printf("Please provide amount of volts in chosen unit:\n");
        scanf("%lf", &amt);
    
    switch(unit){
        case '1':
            x_mv = amt * mv_1;
            x_v = amt * v_1;
                if(amt!=0){
                    printf("%lf uV is equal to: %lf mV \n",amt,x_mv);
                    printf("%lf uV is equal to: %lf V \n",amt,x_v);
                        }
                else if(amt==0){
                    printf("You are multiplying by 0! It is not allowed!\n");
                        }
                break;
        case '2':
            x_mv = amt * mv_2;
            x_v = amt * v_2;
                if(amt!=0){
                    printf("%lf mV is equal to: %lf uV \n",amt,x_mv);
                    printf("%lf mV is equal to: %lf V \n",amt,x_v);
                    }
                else if(amt==0){
                    printf("You are multiplying by 0! It is not allowed!\n");
                    }
                break;
        case '3':
            x_mv = amt * mv_3;
            x_v = amt * v_3;
                if(amt!=0){
                    printf("%lf V is equal to: %lf mV \n",amt,x_mv);
                    printf("%lf V is equal to: %lf uV \n",amt,x_v);
                    }
                else if(amt==0){
                    printf("You are multiplying by 0! It is not allowed!\n");
                    }
                break;
                }
        }
    
        else if(strcmp(myreply,"amp")){
            printf("New code");
        }
    
    
    return 0;
    }
    
    //Into function
    int intro()
    {
        printf("***Welcome in volt unit converter***\n");
        printf("\t   ver. 0.3\n");
        printf("--------------------------------------\n\n");
    }



    Once again, many thanks for the effort and help. https://cboard.cprogramming.com/images/icons/icon14.png
    Rgds,
    T
    Last edited by 1Sh00t; 04-21-2017 at 03:29 PM.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,110
    Code:
        fgets(myreply,sizeof(myreply),stdin);
     
    //!! IF IS NOT READ CORRECTLY
        if(strcmp(myreply,"volt")){
    1. fgets will store "volt\n", which will always compare false with "volt".
    2. strcmp() returns 0 when the strings match. At the moment, you're basically set up for "however if I type amp it still goes same way as volt converter".

    The FAQ shows you how to deal with the trailing \n of fgets().
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Apr 2017
    Posts
    4
    Honestly? I added \n to "volt" and seems its working, however I am not going to say that I understand why (I read FAQ regarding fgets). \n suppose to give a new line, so now idea why it is required by the code. Is there any chance that you could explain that to me in more lets say easier way? So the \n moves to next line or store the whole "volt" string?

    I have written tons of scripts in VBA (yea I know its not real programming language) but for me it is much easier. You want to find string in string? Use InStr() function or you can check if the string is the same: "If your_reply = "good reply" Then" everything seems to be more I would say reasonable.

  8. #8
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    733
    You really need to turn on and turn up your warning levels in your compiler. Compiling with:
    Code:
    gcc -Wall -Wextra -pedantic  -o units units.c
    gcc reports:
    Code:
    units.c: In function ‘main’:
    units.c:24:1: warning: implicit declaration of function ‘intro’ [-Wimplicit-function-declaration]
     intro();
     ^~~~~
    units.c: In function ‘intro’:
    units.c:92:1: warning: control reaches end of non-void function [-Wreturn-type]
     }
     ^
    You need to add a function prototype for indent() above main().
    You declare indent() to return an int, but do not return any value.

    Either declare indent() as:
    Code:
    void indent(void);
    Or return an int from it as defined.

    As for gets() vs fgets(). The string that gets() inputs, does not contain a newline, but fgets() does bring in the terminating newline character. You need to remove that before comparing the string against "volt". I have a function in my private library to do that with any string I input with fgets().

    Again: Better formatting of the code is also recommended. Please see this article on Indent Style. Please choose one type and stick to it.

    Also, spaces in the source code is preferred over tabs. There are many articles online that explain this issue.

  9. #9
    Registered User
    Join Date
    Jun 2015
    Posts
    1,643
    Quote Originally Posted by 1Sh00t View Post
    Honestly? I added \n to "volt" and seems its working, however I am not going to say that I understand why (I read FAQ regarding fgets). \n suppose to give a new line, so now idea why it is required by the code. Is there any chance that you could explain that to me in more lets say easier way? So the \n moves to next line or store the whole "volt" string?

    I have written tons of scripts in VBA (yea I know its not real programming language) but for me it is much easier. You want to find string in string? Use InStr() function or you can check if the string is the same: "If your_reply = "good reply" Then" everything seems to be more I would say reasonable.
    C is more difficult because it doesn't insulate you as much from the underlying machine. Higher level languages like VB hide the details from you which makes programming easier at the cost of flexibility and power. As one demonstration of the power of C, VB is itself written in C. So are Python, Ruby, Java, etc. (although they could of course be written in C++).

    '\n' does not "give a newline". It is simply a character just like any other character which in turn are just small integers. When the '\n' character value is sent to a terminal, the usual response is to go to the next line. When you enter a string, you type in some characters and end the input with the "Return" or "Enter" key, which is interpretted by C as the '\n' character. So the '\n' character is part of the input.

    A string literal like "volt" causes the C compiler to store the characters (including the terminating '\0' character) into memory somewhere and the string literal in the code is replaced by the address of the first character that was stored. That's why you can't simply say str == "volt". str is a character array that has it's own address which will not be equal to the address given to the "volt" string literal. To compare the strings you need to compare each character in turn, which is done with the strcmp (or strncmp, or memcmp) function (or you could write your own function). In order to return information about which string is lexicographically first if they aren't equal, the function returns 0 if they are equal, a negative number if the first is before the second, and a positive number if the first is after the second.

    You can create a wrapper macro that returns a boolean value, true (non-zero) for equal, false (0) for not equal:
    Code:
    #define streq(a, b) (strcmp((a), (b)) == 0)

  10. #10
    Registered User
    Join Date
    Apr 2017
    Posts
    4
    Ok that makes sense. Gonna type something today, and we will see how it goes. Many thanks for all your help!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. What is the unit?
    By windprorobin in forum C Programming
    Replies: 1
    Last Post: 03-09-2017, 10:33 PM
  2. C++ Unit tests
    By Aslaville in forum C++ Programming
    Replies: 3
    Last Post: 01-10-2017, 08:03 AM
  3. Unit Converter
    By rohitdwivedula in forum C++ Programming
    Replies: 1
    Last Post: 02-08-2014, 06:00 PM
  4. Unit test for c++
    By rluceac in forum C++ Programming
    Replies: 5
    Last Post: 04-16-2009, 02:24 AM
  5. Unit converter calculator help
    By ravens199 in forum C++ Programming
    Replies: 23
    Last Post: 01-13-2008, 09:30 PM

Tags for this Thread