0

i'm practicing strings now and what i try to do in this program is print something like: hello world into HellO WorlD as an output.

My code is the following one:

#include <stdio.h>

#include <string.h>

void convertir(char cadena[200]){

  int length = strlen(cadena);

  int i;

    printf("%c", cadena[0]-32); // Prints letter in caps

    for(i=1;i<length-1;i++){

      if(cadena[i] == ' '){ // Search if there is space

        printf("%c", cadena[i-1]-32);

        i=i+1; // Adds vaule on i with accumulator to make caps the letter after the space

        printf(" %c", cadena[i]-32); // prints letter in caps after space

      } else {

      printf("%c", cadena[i]); // prints everything in the string

      }

    }

    printf("%c", cadena[length-1]-32);

}

int main(int argc, char const *argv[]) {

  char cadena[200];

  printf("Introduce un texto: ");

  gets(cadena);

  convertir(cadena);

  return 0;

}

What the code compiled returns me after typing hello world is: HelloO WorlD, i'm trying to replace that o in HelloO but i'm getting confused...

Any help is appreciated.

Thank you.

Daniel Logvin
  • 502
  • 7
  • 26
  • Should probably check if letter is lowercase before this: `printf("%c", cadena[0]-32);` – Fiddling Bits Oct 28 '18 at 21:43
  • So, to understand, you want to capitalize the first and last letter of each word? – Fiddling Bits Oct 28 '18 at 21:44
  • yes sir, i do want to capitalize the first and last letter of each word – Daniel Logvin Oct 28 '18 at 21:45
  • It's not a good idea to increment `i` in the `for` loop header and in the body as it makes the code more difficult to interpret. – Fiddling Bits Oct 28 '18 at 21:46
  • True, but... how can i solve this problem in the way i'm making it? – Daniel Logvin Oct 28 '18 at 21:50
  • 2
    consider the following string: "a a a". I suppose you expect to be able to print "A A A" - now try to think about your logic, see if it fits (well.. you already know it doesn't...), and try to come up with a different plan. This is *not* about programming, it's about logic and planning. Good luck! – Amit Oct 28 '18 at 21:51
  • Please read [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) – Weather Vane Oct 28 '18 at 22:01

3 Answers3

1

I made the following changes to your for loop and it appears to work as you expect it to:

for(i=1;i<length-1;i++)
{
    if(cadena[i + 1] == ' ') /*** Look If Next Character Is A Space ***/
    {
        printf("%c", cadena[i]-32); /*** Print Current Character In Uppercase ***/
        i=i+1; // Adds vaule on i with accumulator to make caps the letter after the space
        printf(" %c", cadena[i + 1]-32); /*** Print Character After Space In Caps ***/
        i=i+1; // Adds vaule on i with accumulator to make caps the letter after the space
    }
    else
    {
        printf("%c", cadena[i]); // prints everything in the string
    }
}

Output:

$ ./main.exe
Introduce un texto: hello world
HellO WorlD

Moving forward, there are several things you should do to make your program more robust:

  1. Don't assume there aren't leading spaces (or whitespace)
  2. Don't assume each character is lowercase
  3. Don't assume each character is a letter
  4. Don't assume there is only one space (or whitespace) between words
Fiddling Bits
  • 8,712
  • 3
  • 28
  • 46
1

Any help is appreciated.

Use isalpha() to detect if a char is part of a word.

Use toupper() to convert to an uppercase character.

Use unsigned char for isalpha(), toupper() to avoid UB with negative char values.

Employ a boolean to keep track if a beginning of a word is possible.

#include <ctpye.h>
#include <stdbool.h>

void convertir(const char *cadena) {
  const unsigned char *s = (const unsigned char *) cadena;
  bool potential_start_of_word = true;

  while (*s) {
    // If next character is not an alpha or we area at the start of a word ...
    if (!isapha(s[1]) || potential_start_of_word) {
      printf("%c", toupper(*s));
    } else {
      printf("%c", *s);
    }
    potential_start_of_word = !isapha(*s);
    s++;
  }
}

No need for strlen(cadena)

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

You can use ctype.h's toupper() function or provide your own implementation. Something like this:

int toupper(int c) {
    return (c-32);
}

And then use it like this:

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

void convertir(char cadena[200]){

    int length = strlen(cadena);
    int i;

    cadena[0] = toupper(cadena[0]);
    cadena[length-1] = toupper(cadena[length-1]);

    for(i=0; i<length; i++){

        if(cadena[i] == ' '){ // Search if there is space
            cadena[i-1] = toupper(cadena[i-1]);
            if (i+1 < length) cadena[i+1] = toupper(cadena[i+1]);
        }
    }

    printf("%s\n", cadena);

}

int main(int argc, char *argv[]) {
    char cadena[200];
    printf("Introduce un texto: ");
    gets(cadena);
    convertir(cadena);
    return 0;
}
Tretorn
  • 365
  • 1
  • 16
  • This doesn't work as required by OP: `$ ./main.exe Introduce un texto: hello world Hello World`. First and last character of word should be capitalized. – Fiddling Bits Oct 28 '18 at 22:05
  • Please note that `int toupper(int c);` is already a library function or macro requiring `#include ` and does not depend on ASCII encoding. Also your own `toupper` function will fail when passed any character except a lowercase ASCII character. – Weather Vane Oct 28 '18 at 22:07
  • @FiddlingBits yeah, i noticed he wanted the first letter also. Edited – Tretorn Oct 28 '18 at 22:11
  • @WeatherVane of course it would be safer to use the ctype toupper. That's what i tried to say. Edited to clarify – Tretorn Oct 28 '18 at 22:12