Thread: Function always returning 0

  1. #1
    Registered User
    Join Date
    Oct 2020
    Posts
    69

    Function always returning 0

    The statement is:
    Write a program that prints all entities of the form &name; (where name is formed of letters) appearing in the input, separated by one space.
    Code:
    
    
    Code:
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    #define MAX 100
    int checkWord(char word[])
    {
        size_t len = strlen(word);
        for(int i = 0; i < strlen(word); i++)
        {
            if(!isalpha(word[i]) || (word[0] != '&') || (word[len-1] != ';'))
            {
                return 0;
            }
        }
        return 1;
    }
    int main()
    {
        char s[MAX];
        while(fgets(s, MAX, stdin))
        {
            char* word = strtok(s, " ");
            while(word != NULL)
            {
               // printf("%s\n", word);
               printf("%d\n", checkWord(word));
                if(checkWord(word) == 1)
                {
                    printf("%s ", word);
                }
                word = strtok(NULL, " ");
                //printf("%s", word);
            }
        }
        return 0;
    }


    The program should work well but checkWord always returns 0 and never actually enters the if block. I don't understand what I'm missing, checkWord checks if the word is formed by letters only, starts with '&' and ends ';' but for the input:
    john goes to &school; everyday
    Output:
    0
    0
    0
    0 // this should be 1 and therefore &school; should be printed
    0

    What am I doing wrong?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,304
    The check for '&' and ';' should be done just once, outside of the loop. You'll just need to adjust the start and end conditions of the loop to avoid checking them in the loop, because that's why your current checkWord returns 0: isalpha(word[0]) would be 0 for a valid input. (Speaking of which, if you should have used len rather than strlen(word) in the loop condition, though now it'll be len-1.)
    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

  3. #3
    Registered User
    Join Date
    Oct 2020
    Posts
    69
    Quote Originally Posted by laserlight View Post
    The check for '&' and ';' should be done just once, outside of the loop. You'll just need to adjust the start and end conditions of the loop to avoid checking them in the loop, because that's why your current checkWord returns 0: isalpha(word[0]) would be 0 for a valid input. (Speaking of which, if you should have used len rather than strlen(word) in the loop condition, though now it'll be len-1.)
    so my function now looks like this
    Code:
    int checkWord(char word[])
    {
        size_t len = strlen(word);
        if(word[0] != '&' || word[len-1] != ';')
            return 0;
        else
            return 1;
        for(int i = 1; i < len-1; i++)
        {
            if(!isalpha(word[i]))
            {
                return 0;
            }
        }
        return 1;
    }
    which, is still not working, I've also tried putting the for loop inside the if block but it still returns 0.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,304
    You have to remove the else return 1 otherwise your loop will be dead code.
    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

  5. #5
    Registered User
    Join Date
    Oct 2020
    Posts
    69
    Yeah, I added that afterwards because I didn't know what else to try, but it doesn't work without it either.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,304
    It works for me:
    Code:
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    
    int checkWord(char word[])
    {
        size_t len = strlen(word);
        if(word[0] != '&' || word[len-1] != ';')
            return 0;
    
        for(int i = 1; i < len-1; i++)
        {
            if(!isalpha(word[i]))
            {
                return 0;
            }
        }
        return 1;
    }
    
    int main(void)
    {
        if (checkWord("&name;"))
        {
            puts("pass");
        }
        if (!checkWord("name"))
        {
            puts("pass");
        }
        if (!checkWord("&name"))
        {
            puts("pass");
        }
        if (!checkWord("name;"))
        {
            puts("pass");
        }
        return 0;
    }
    When I change the main function to the one you used in post #1 and enter your provided sample input, I get:
    Code:
    john goes to &school; everyday
    0
    0
    0
    1
    &school; 0
    which proves that it works (at least other than for certain edge cases, e.g., you need to remove the trailing newline character from fgets).

    So, if it still "doesn't work", you need to post an update on the exact program that you tried, along with the sample input, expected output, and actual output.
    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

  7. #7
    Registered User
    Join Date
    Oct 2020
    Posts
    69
    Code:
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    #define MAX 100
    int checkWord(char word[])
    {
        size_t len = strlen(word);
        if(word[0] != '&' || word[len-1] != ';')
            return 0;
        for(int i = 1; i < len-1; i++)
        {
            if(!isalpha(word[i]))
            {
                return 0;
            }
        }
        return 1;
    }
    int main()
    {
        char s[MAX];
        while(fgets(s, MAX, stdin))
        {
            char* word = strtok(s, " ");
            while(word != NULL)
            {
               // printf("%s\n", word);
               printf("%d\n", checkWord(word));
                if(checkWord(word) == 1)
                {
                    printf("%s\n", word);
                }
                word = strtok(NULL, " ");
                //printf("%s", word);
            }
        }
        return 0;
    }
    Input: &john; goes to &school; everyday by &bus;
    Output:
    1
    &john;
    0
    0
    1
    &school;
    0
    0
    0
    Expected Output:
    1
    &john;
    0
    0
    1
    &school;
    0
    1
    &bus;




    Input: john goes to &school;
    Output:
    0
    0
    0
    0
    Expected Output:
    0
    0
    0
    1
    &school;

    So yes, you're right, it's printing the right output for the input I've put in the example, but it seems that my program doesn't return 1 unless there is another word after &name;. It didn't print any "1" for me because I only tried the second input after modifying the code.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,304
    You need to remove the trailing newline character that fgets reads and stores in the string.
    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

  9. #9
    Registered User
    Join Date
    Oct 2020
    Posts
    69
    Quote Originally Posted by laserlight View Post
    You need to remove the trailing newline character that fgets reads and stores in the string.
    It's working now, thank you!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 09-06-2011, 02:59 PM
  2. Returning a function pointer from a function
    By StainedBlue in forum C++ Programming
    Replies: 4
    Last Post: 11-01-2010, 10:26 PM
  3. Function returning pointer to function
    By DL1 in forum C++ Programming
    Replies: 6
    Last Post: 08-07-2009, 10:27 AM
  4. Error: _ defined as a function returning a function?
    By Jardon in forum C Programming
    Replies: 15
    Last Post: 07-29-2009, 11:53 AM
  5. Recursion: base case returning 1, function returning 0
    By yougene in forum C Programming
    Replies: 5
    Last Post: 09-07-2007, 05:38 PM

Tags for this Thread