1

I have tried for hours to edit this code to work the way I want it to. I am meant to code a program to track the frequency of how often an underscore '_' and an exclamation point '!' appear in a sentence input by a user: _Hi_there!!!

Specifications that must be used and/or not deleted -This function prototype must remain unmodified: -The getchar() method must be used to hold the value of the sentence input by the user.

Now I have this code after hours of struggling to get a proper output:

#include <stdio.h>

int num_count;
int num_exclamation_count;
char ch;
char s[1000]; 
void count(int* num_, int* num_exclamation)
{       
    int i;
    for(i = 0; s[i] != '\0'; i++)
    {
        if((s[i] == getchar()) && (s[i] == '_'))
        {
            ++num_count;
            *num_ = num_count;  
        }
        else if((s[i] == getchar()) && (s[i] == '!'))
        {
            ++num_exclamation_count;
            *num_exclamation = num_exclamation_count;
        }
        else
        {
            continue;
        }
    }

}

int main (void)
{
    int num_user, num_exclamation_user;
    printf("Enter a sentence: ");
    do
    {
        ch = getchar();
    }while(ch != '\n');
    count(&num_user, &num_exclamation_user);

    printf("There are %d underscores and %d exclamation points in the 
    sentence.\n", num_user, num_exclamation_user);

    return 0;
}

The output I get is as follows:

There are 0 underscores and 0 exclamation points in the sentence.

I tried every variation of while or if or do-while statements I could conjure in my mind or find available online and I get nowhere but further away. If someone could thoroughly explain how I arrange which conditional statement/loop with the getchar() method and necessary variables, that would be awesome. Open to criticism as well if I blatantly screwed something up or passed over an obvious issue, do not be scared to hurt my feelings. I only want to learn and will be my only mindset as I am assisted with this problem.

Thank you.

  • The above function prototype that needed to be used for the method was: void count(int* num_, int* num_exclamation); –  Feb 21 '18 at 23:12
  • 1
    `char s[1000]; ` is not initialized. The first time in your loop `for(i = 0; s[i] != '\0'; i++)` , s[0] will contain a random value. 2) and probably you want a single `=` here: `if((s[i] == getchar())` . – wildplasser Feb 21 '18 at 23:13
  • I tried your advice wildplasser and neither did any benefit. I believe in my if statements, I have an extra condition that is unnecessary I just can't tell which one or if that is even the issue.. –  Feb 21 '18 at 23:24
  • @wildplasser Global `char s[1000];` is initialized to zeros. – chux - Reinstate Monica Feb 21 '18 at 23:35
  • Note that `s[]` is nowhere assigned in the entire program. And your loop `do { ch = getchar(); }while(ch != '\n');` essentially waits for a CR to be input, ignoring everything typed in. – wildplasser Feb 21 '18 at 23:36
  • @chux You are correct. I'd never expected a one letter identifier for a global/static variable. ;-[ – wildplasser Feb 21 '18 at 23:38

5 Answers5

1

your program is getting a "sentence" as user input then ignore it completely.

you are not intializing this variables.

int num_user;
int num_exclamation_user;

I'd suggest that you store the string input somewhere(e.g in s) like this :

fgets (s, 1000, stdin);

instead of your while do loop. Then in your count function just compare s[i] with '_' and '!' like this :

if(s[i] == '_'){

        ++num_count;
        *num_ = num_count;  
    }
else if (s[i] == '!')
    {
        ++num_exclamation_count;
        *num_exclamation = num_exclamation_count; 
    }
    else
    {
        continue;
    }

because with s[i] == getchar() you are asking the user to re-type a character.

nabil.douss
  • 634
  • 4
  • 10
1

OP's code has these errors:

  1. Not initializing num_user, num_exclamation_user in main(). Set them to 0

  2. Unneeded code of do { ch = getchar(); while (ch != '\n'); in main(). Delete

  3. Looking for a null character from input with for(i = 0; s[i] != '\0'; i++) prevented loop iteration as s[0] is initialized to 01. User input is lines, not a string. Look for a '\n'. Also assign s[i] = getchar(), not compare s[i] == getchar() @wildplasser

    //for (i = 0; s[i] != '\0'; i++) {
    for (i = 0; i < 1000 && (s[i] = getchar()) != '\n'; i++) {
    
  4. Code calls getchar() more than once per loop.

    // if ((s[i] == getchar()) && (s[i] == '_')) {
    if (s[i] == '_') {
      ...
    // } else if ((s[i] == getchar()) && (s[i] == '!')) {
    } else if (s[i] == '!') {
    

Although there are other learner issues (e.g. better to use int ch for input than a char s[i]), fixing the above will solve OP's problem.

1 Global integer types like the array s[1000] elements are initialized to 0.

Short count() below. Think it out before mousing over.

void count(int* num_, int* num_exclamation) {
int ch; while ((ch = getchar()) != '\n' && ch != EOF) {
if (ch == '') {
(*num
)++;
} else if (ch == '!') {
(*num_)++;
}
}
}

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

How does the string s get a reference to what the user has input?

You might want to insert ch into the string in the main loop.

int count = 0;
do
{
    ch = getchar();
    s[count] = ch;
    count = count + 1;
}while(ch != '\n');

Of course, the user shouldn't type more than 1000 characters, in which case this would fail. But, you can just add a condition in the while loop to check for count to fix that. In general though, you should look at using secure input methods, which is probably outside the scope of your problem and constraints, but it is good to know.

Why have you placed getchar() inside the count() function? Do you intend to accept more characters from stdin (console)? If not, you would simply remove getchar() parts from that function

void count(int* num_, int* num_exclamation)
{       
    int i;
    for(i = 0; s[i] != '\0'; i++)
    {
        if(s[i] == '_')
        {
            ++num_count;
            *num_ = num_count;  
        }
        else if(s[i] == '!')
        {
            ++num_exclamation_count;
            *num_exclamation = num_exclamation_count;
        }
        // This is not really required
        //else
        //{
        //    continue;
        //}
    }

}

Also, initialize num_user and num_exclamation_user in the main() function.

0

getchar() is a function that pulls the next character from the input and returns it. Every time you call it the next letter is retrieved.

In your code, the loop in main() gets the entire input and ... doesn't put it anywhere, so it is lost forever.

It seems like you are supposed to save it to s[]. Then, in count(), you can refer to the current character as s[I] instead of calling getchar(), which has no more input to return.

Jeff
  • 1,234
  • 8
  • 16
0

getchar() return type is int, so change the ch type to int and add a check for EOF. Also, you don't want the \n character to be part of input stored in s array so, replace do while loop with while loop.
You don't need the globals - num_count, num_exclamation_count and ch. Try not to use globals as much as possible. Even you don't need the buffer s to be declared as a global variable. You can declare it in main() and pass it to function count() as an argument but for this, you need to modify the count() prototype and seems that this is something that you don't want to do.
The other answers have already pointed out the errors in your code. You can do:

#include <stdio.h>

#define BUF_SZ 1000

char s[BUF_SZ];

void count(int* num_, int* num_exclamation)
{
    int i;
    for(i = 0; s[i] != '\0'; i++)
    {
        if(s[i] == '_')
        {
            ++(*num_);
        }
        else if(s[i] == '!')
        {
            ++(*num_exclamation);
        }
    }
}

int main (void)
{
    int num_user = 0, num_exclamation_user = 0, i = 0, ch;

    printf("Enter a sentence: ");

    while ((ch = getchar()) != '\n' && ch != EOF)
    {
        if (i < (sizeof(s) - 1)) { // sizeof(s) - 1, to keep the space for terminating null character
            s[i++] = ch;
        } else {
            break; //discard the input beyond the size of buffer s
        }
    }

    s[i] = '\0';
    count(&num_user, &num_exclamation_user);

    printf("There are %d underscores and %d exclamation points in the sentence.\n", num_user, num_exclamation_user);

    return 0;
}
H.S.
  • 11,654
  • 2
  • 15
  • 32