1

I'm doing the CS50 course in C and am working on the problem set from week 2. I'm an absolute beginner so there's probably a lot wrong with my code. For now, I'm trying to create a function that checks if the user has correctly used the command line input and if that input consists of only integers.

this is my code:

#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

bool only_digits(string s);

int main(int argc, string argv[])
{
    if (argc == 2 & only_digits > 0)
    {
        printf("test\n");
    }
    else
    {
        printf("usage: ./caesar key\n");
    }
}

bool only_digits(string s)
{
    for (int i = 0, n = strlen(s); i < n; i++)
        {
            if (isdigit(i))
            {
                return 0;
            }

            else
            {
                return 1;
            }
        }
}

This is the error:

caesar/ $ make caesar 
caesar.c:34:1: error: non-void function does not return a value in all control paths [-Werror,-Wreturn-type]
}
^
1 error generated.

Thanks in advance, and excuse me for the many mistakes there probably are in the code. make: *** [: caesar] Error 1

dariocodes
  • 133
  • 1
  • 1
  • 7
  • 1
    Your loop will execute either 0 or 1 times. One of those returns is misplaced... (Walk it through with your debugger or on paper if you need to) – ikegami Aug 27 '22 at 17:04
  • 3
    when length is 0, where is the return? – OznOg Aug 27 '22 at 17:07
  • The compiler doesn't always check for the actual path taken, but sees that there is no `return X;` after the loop. – Weather Vane Aug 27 '22 at 17:09
  • 1
    The loop should return `false` when there is *not* a digit, otherwise rerturn `true` after the loop. The function is also called incorrectly: `only_digits > 0` should be `only_digits(argv[1]) == true` – Weather Vane Aug 27 '22 at 17:11
  • Opinion, but common convention is to place an if with any conditions which cause a usage message and exit of the function to be printed at the beginning of `main` and return 1. If the program passes this you can assume it got the rightt number of arguments or the right kind and proceed. – Chris Aug 27 '22 at 17:37

2 Answers2

1

The logic of your function doesn't match its name. Presumably, you want only_digits to check if the passed in string is comprised entirely of digits. However, you return 0 (false) when you find a digit, that makes no sense. You're also not calling the function correctly:

#include <cs50.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

int main(int argc, string argv[])
{
    // use && for logical AND, & is bitwise AND
    // Pass argv[1] to only_digits
    if ((argc == 2) && only_digits(argv[1]) == true)
    {
        
        printf("test\n");
    }
    else
    {
        printf("usage: ./caesar key\n");
    }
}

bool only_digits(string s)
{
    // strlen returns a size_t type, use that
    size_t n = strlen(s);
    for (size_t i = 0; i < n; i++)
    {
        // check each digit. If it's _not_ a digit, then we're
        // done, no point in checking the rest of the string
        if (!isdigit(s[i]))
        {
            return false;
        }
    }

    // we've looped thru the entire string. If we make it here
    // and haven't returned false, then we know every char in
    // the string is a digit, return true
    return true;
}

Demo

yano
  • 4,827
  • 2
  • 23
  • 35
  • 1
    Thank you, this helped me greatly and the notes are kindly appreciated. It can be quite demotivating to simply not comprehend, but your instructions give me some renewed motivation to continue! – dariocodes Aug 27 '22 at 17:38
  • 1
    @dariocodes awesome! Hang in there! Coding can be extremely frustrating and confusing, especially starting out, but quite rewarding once you start to figure things out and make them work. Feel free to ask if something in my answer isn't clear. – yano Aug 27 '22 at 22:00
0

If you pass empty string "" it will not enter the for loop and all your return statements will be skipped.

bool only_digits(string s)
{
    for (int i = 0, n = strlen(s); i < n; i++)
        {
            if (isdigit((unsigned char)i))
            {
                return false;
            }

            else
            {
                return true;
            }
        }
    return false;
}

or

bool only_digits(string s)
{
    for (int i = 0, n = strlen(s); i < n || !n; i++)
        {
            if (isdigit((unsigned char)i))
            {
                return false;
            }

            else
            {
                return true;
            }
        }
}
0___________
  • 60,014
  • 4
  • 34
  • 74