Ondřej Javorský
Ondřej Javorský

Reputation: 475

C language - return a value from function as function parameter

I have a problem with my homework. I need to count quantity of upper case and quantity of vowels in string. Unfortunately, it always returns number 0 which looks as it doesn't change in function. Everything works until this one.

Here is my code:

#include <stdio.h>
#include <conio.h>
#include <string.h>

char *StringChange(char *text, int *upper, int *chars);

int main(void) {
    char text[40];
    int upper, chars;

    puts("Type a string");
    gets(text);

    StringChange(text, &upper, &chars);

    puts("Change words to start with upper case and change white spece to *");
    puts(text);
    printf("Quantity of upper case in string: %d\n", upper);
    printf("Quantity of vowels: %d", chars);

    getch();
    return 0;
}

char *StringChange(char *text, int *upper, int *chars) {
    int i, length;

    length = strlen(text);

    for (i = 1; i <= length; i++) {
        if (text[i - 1] == '*' && (text[i] >= 'a' && text[i] <= 'z')) {
            text[i] = text[i] - 32;
        }
        if (text[i] == ' ') {
            text[i] = '*';
        }
        if (text[i] >= 'A' && text[i] <= 'Z') {
            *upper = *upper + 1;
            /* *upper++; that also doesn't work */
        }
        if (text[i] == 'a' || text[i] == 'e' || text[i] == 'i' || text[i] == 'o' || text[i] == 'u' || text[i] == 'y') {
            *chars = *chars + 1;
            /* *chars++; that also doesn't work */
        }
    }

    if (text[0] >= 'a' && text[0] <= 'z') {
        text[0] = text[0] - 32;
    }

    return (text);
}

Upvotes: 1

Views: 100

Answers (2)

Dave Costa
Dave Costa

Reputation: 48111

I tried your code and I do get non-zero results -- depending on the input, of course, so maybe you are only testing on strings that produce zero.

However, the results are not always correct. There are two problems I found in the code:

1) As pointed out in a comment, you should initialize upper and chars to 0.

2) You are starting the loop at index 1, not index 0. I think you did this so you could look at text[i-1] inside the loop, but it is causing you to exclude the first character from your totals. You should start the loop index and 0 and figure out a different way to handle it within the loop. (Hint - note that the first if within the loop and the one following the loop have similar conditions and the same body.)

Upvotes: 2

chqrlie
chqrlie

Reputation: 144685

There are multiple issues in your code:

  • you should never use gets().
  • the variables upper and chars are not initialized
  • the function StringChange make a special case of text[0] but does not update the counts for this initial byte.
  • you hard code the conversion of lowercase to uppercase for ASCII.
  • you should stop at the end of the string
  • all white space is not replaced, on whitespace followed by a lowercase letter.
  • uppercase vowels should be counted too.

Here is a modified version:

#include <stdio.h>

char *StringChange(char *text, int *upper, int *chars);

int main(void) {
    char text[200];
    int upper, vowels;

    puts("Type a string");
    if (fgets(text, sizeof text, stdin)) {
        StringChange(text, &upper, &chars);

        puts("Change words to start with upper case and change white space to *");
        puts(text);
        printf("Quantity of upper case in string: %d\n", upper);
        printf("Quantity of vowels: %d\n", vowels);
    }
    getchar();
    return 0;
}

char *StringChange(char *text, int *upper, int *vowels) {
    int i, at_start = 1;

    *upper = *vowels = 0;
    for (i = 0; text[i] != '\0'; i++) {
        char c = text[i];
        if (at_start && c >= 'a' && c <= 'z') {
            c += 'A' - 'a';
            text[i] = c;
        }
        if (c == ' ') {
            c = '*';
            text[i] = c;
            at_start = 1;
        } else {
            at_start = 0;
        }
        if (c >= 'A' && c <= 'Z') {
            (*upper)++;   // *upper++ would just increment the pointer, leading to undefined behavior
        }
        if (strchr("aeiouyAEIOUY", c) {
            (*vowels)++;
        }
    }
    return text;
}

Upvotes: 1

Related Questions