hey.. Ive done a bit of java and im new at C... so forgive the inexperience/noobage here.. I got 2 problems, I want my program to read in 2 fractions and print the product.. and whenever I press enter without entering any value, ie. a null input, I want it to go back to the main menu.. I have left out the main menu code.. here's the rest of the relevant bits:

/****************************************************************************
* Function nullCheck() checks if a null is entered to return to menu
****************************************************************************/
void nullCheck(char cNum1[])
{
     if(&cNum1[1] == NULL)
     {    main();
     }
}

/****************************************************************************
* Function fractions() calculates the sum of 2 fractions 
****************************************************************************/
void fractions()
{    
     int i, nProd, dProd, iNum1, iNum2, iDen1, iDen2;
     char cNum1[4];
     char cNum2[4];
     char cDen1[4];
     char cDen2[4]; 
     
     printf("Enter fraction 1: ");
     scanf("%s/%s", cNum1, cDen1);
     //nullCheck(cNum1);
     
     printf("Enter fraction 2: "); 
     scanf("%s/%s", cNum2, cDen2);
     //nullCheck(cNum2);
     //printf("%d", iNum1);
     
     //(THE PRINTF STATEMENTS ARE FOR DEBUGGING PURPOSES)
     iNum1 = atoi(cNum1);         //works
           printf("%d", iNum1); 
     iNum2 = atoi(cNum2);         //works
           printf("%d", iNum2);
     iDen1 = atoi(cDen1);         //doesn't work
           printf("%d", iDen1);
     iDen2 = atoi(cDen2);         //doesn't work
           printf("%d", iDen2);

problem 1: It prints out the numerators correctly, but not the denominators.
problem 2: I can't seem to get the "enter a null and go back to the main menu" function to work.

"%s/%s" won't do as you expect. The %s specifier reads anything and everything up to whitespace, so if your input is 1/2, the first %s will read "1/2". The second %s isn't executed because the next character doesn't match '/', so you're stuck with an uninitialized array. It should go without saying that subsequent calls to atoi on an uninitialized array are unlikely to do what you want.

To correctly parse the expression, you need to stop reading at a slash: "%[^/]/%s". This assumes the input won't have embedded whitespace, such as "1 / 2", though that can be handled as well by extracting leading whitespace: "%[^/ ] / %s".

>whenever I press enter without entering any value, ie. a null input
I'll just say that you have a misunderstanding here. There's no such thing as a null input. You can signal end-of-file, but that's as close as it gets. Pressing Enter will send a newline to stdin, which you then need to process. However, when accepting whitespace (as with scanf's %s specifier), that newline will simply be ignored. You need to read the expression as a full string, then parse it manually for more control:

char buf[BUFSIZ];

printf("Enter fraction 1: ");
fflush(stdout);

if (fgets(buf, sizeof buf, stdin) != NULL && buf[0] != '\n') {
    char *end;

    // Error handling omitted for brevity
    iNum1 = (int)strtol(buf, &end, 0);
    end += strspn(end, " \t\r\n\f\v");
         
    if (*end != '\0' && *end != '/') {
        fputs("Invalid expression format", stderr);
        exit(EXIT_FAILURE);
    }

    iNum2 = (int)strtol(end + 1, NULL, 0);
}

>iNum1 = atoi(cNum1);
Do me a favor and forget that atoi exists. It's very difficult to use safely, while strtol is very easy to use safely and does the same thing with more flexibility.

>if(&cNum1[1] == NULL)
I can't begin to express how incorrect this condition is, both in terms of doing what you want and in terms of making any sense at all period. Perhaps my explanation of "entering null" above will clear things up, but you also need to study pointers a bit more. If you don't understand pointers thoroughly, you'll have a hard time with C.

>main();
No. Never, ever, ever, EVER, call main recursively[1]. It's a stupid solution encouraged by stupid people and will only make you miserable. Use a loop. That's what they're there for.


[1] Unless you're writing an entry for the IOCCC, but then you're probably proficient enough to understand the pitfalls and benefits for obfuscation.

Narue... i jus tried out all your suggestions... and they work amazingly.. i read the thing in as a string.. and then parsed it into wutever i needed it to be..
i used fgets() instead of scanf and equated it to "\n" so it goes back to the main menu.... thnx a heap!! appreciate it... :D

This article has been dead for over six months. Start a new discussion instead.