-2

A word is entered by the user. The program first converts all the characters into lower case and then capitalizes only the first character and then prints the word.

I have tried it this way but it didn't work:

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

main()
{
   char word[100][50];
   int i, j, n;

   printf("How many words: ");
   scanf("%d", &n);

   printf("Enter the words one by one\n");
   for (i = 1; i <= n; i++)
   {
      scanf("%s", word[i]);
      strlwr(word[i]);
   }

   for (i = 1; i <= n; i++)
       toupper('word[i][1]');

   for (i = 1; i <= n; i++)
       printf("%s\n", word[i]);
}       

For example, when I input "RODRICK", it gives the output as "rodrick" instead of "Rodrick".

Swordfish
  • 12,971
  • 3
  • 21
  • 43
Esha
  • 113
  • 3
  • 6
    `toupper('word[i][1]');` - look at that *very* carefully. and consider where the quotes are. Then look up how [`toupper`](https://en.cppreference.com/w/c/string/byte/toupper) works, because even in fixing the quotes you're still not using it correctly. Frankly i'm amazed you didn't get at least one compile time warning yelling at you about a potentially undesired multi-byte char literal. If you didn't, you seriously need to turn up your warning levels and fix the problems flagged, not ignore them. – WhozCraig May 18 '19 at 06:38

3 Answers3

3

In C, anything within single quotes are integer character constants.

As specified in the standard.

An integer character constant is a sequence of one or more multibyte characters enclosed in single-quotes, as in 'x'. A wide character constant is the same, except prefixed by the letter L. With a few exceptions detailed later, the elements of the sequence are any members of the source character set; they are mapped in an implementation-defined manner to members of the execution character set.

Since there are multiple bytes in 'word[i][1]', behavior is implementation defined.

What you probably wanted was

word[i][0] = toupper(word[i][0]);

In C, indexing starts from 0 and not 1.

And toupper() just returns a value. The original array element value is not modified. You can assign the value returned by toupper() back to word[i][0].

You should also include the ctype.h header file for the toupper() function.


And strlwr() is a non-standard function. You could use a loop and the tolower() function instead. See How do I lowercase a string in C?.


scanf() is not the best way to read user input and even if you use it, you should check the return value to see if it succeeded.

Instead you could use fgets()-sscanf() combination.

J...S
  • 5,079
  • 1
  • 20
  • 35
  • 1
    I was still thinking how to answer the actual problem. Good one. And thanks for being faster than the typo-close-voters. I wish I could upvote each good part of the answer separatly... – Yunnosch May 18 '19 at 06:56
  • *Instead you could use `fgets()-sscanf()` combination.* – What difference would it make to first stuff a line into a string and then do the same `scanf()` does!? -1 for not addressing TRWTF. – Swordfish May 18 '19 at 07:15
  • @Swordfish http://c-faq.com/stdio/scanfprobs.html ? – J...S May 18 '19 at 07:21
  • @J...S from your link: *it's hard to guarantee that the receiving buffer won't overflow.* – no, that isn't "hard". – Swordfish May 18 '19 at 07:23
  • Does that mean that while using non standard functions like strlwr() we do not require to store it in another variable like word[i] ,like we need to do in case of toupper()? – Esha May 19 '19 at 09:42
  • @Priyanka You don't have to store it in a different variable when using `toupper()`: `word[i] = toupper(word[i]);` – Swordfish May 19 '19 at 22:56
  • @Priyanka `strlwr()` takes in the whole string and modifies it in in-place. `toupper()` considers the string character by character and if you need to modify it you have to explicitly assign it to the right part of the string. It's better to avoid using non-standard functions like `strlwr(). – J...S May 20 '19 at 06:09
0

Your main()-function is missing a return type. According to the language standard main() shall return an integer. When a function doesn't take arguments, it's parameter list should be void, so:

int main(void)

Here

printf("How many words: ");
scanf("%d", &n);

you don't check if the user enters a number which is in range of your array word. Always check user input! n should be within the range [1, 100]:

printf("How many words: ");
if (scanf("%d", &n) != 1 || n < 1 || 100 < n) {
    // handle the input error, maybe exit the program
}

Please have a look at the reference for scanf(). scanf() returns the number of receiving arguments successfully assigned. So if scanf("%d", &n) doesn't return 1 an integer couldn't be read.


printf("Enter the words one by one\n");
for (i = 1; i <= n; i++)

Arrays in C and C++ start at the index 0 and the last valid index is size - 1. For your array word the first valid index is word[0] and the last is word[99]. You have to iterate from i = 0 to i < n:

printf("Enter the words one by one\n");
for (i = 0; i < n; ++i)

scanf("%s", word[i]);

Don't ever use the %s format specifier without specifying a WIDTH to limit the number of characters scanf() assigns to the argument. Again, please have a look at the documentation for scanf().

scanf("%49s", word[i]);

Not specifying a WIDTH is a Buffer Overflow waiting to happen. If the users input is longer than 49 characters the rest will stay in stdins buffer and will be read by the next call to an input function. If you don't want that to happen but rather ignore the rest you'd have to think about more sophisticated ways to handle input.


strlwr(word[i]);

Please note that strlwr() is no standard library function. See strupr() and strlwr() in string.h part are of the ANSI standard?


for (i = 1; i <= n; i++)
    toupper('word[i][1]');

Again, iterate from i = 0 to i < n. The function toupper() takes a character (well, actually an int because it also handles EOF) and if it is a lowercase character) it returns it's capitalized equivalent. You don't do anything with the returned value.

for (i = 0; i < n; ++i)
    word[i][0] = toupper(word[i][0]);  // assign the result of toupper()

for (i = 1; i <= n; i++)
    printf("%s\n", word[i]);

With all that's been said already:

for (i = 0; i < n; ++i)
    printf("%s\n", word[i]);

Please note that you can simply use puts() if you want to print a string followed by a newline character.


Putting all of that together:

#include <stdlib.h>  // EXIT_FAILURE
#include <stdio.h>   // printf(), scanf(), puts()
#include <ctype.h>   // toupper()
#include <string.h>  // _strlwr() (Microsoft)

int main(void)
{
    printf("How many words: ");
    int n;
    if (scanf("%d", &n) != 1 || n < 1 || 100 < n) {
        puts("Input error. :(\n");
        return EXIT_FAILURE;
    }

    char word[100][50];
    puts("Enter the words one by one\n");
    for (int i = 0; i < n; ++i)
    {
        if (scanf("%49s", word[i]) != 1) {
            puts("Input error. :(\n");
            return EXIT_FAILURE;
        }

        _strlwr(word[i]);
    }

    for (int i = 0; i < n; ++i)
        word[i][0] = (char)toupper(word[i][0]);

    for (int i = 0; i < n; ++i)
        puts(word[i]);
}
Swordfish
  • 12,971
  • 3
  • 21
  • 43
-1

It is important to know when you use a function what it take as an argument and what it returns, and which lib contains it. I left notes throughout the code to explain the changes I have made to your code

good luck!

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

int main()
{
   char word[100][50];
   int i, n;

   printf("How many words: ");
   scanf("%d", &n);

   printf("Enter the words one by one\n");
   for (i = 0; i < n; i++)
   {
    //reconsider using scanf as it is an unsafe function and check input
    //length is under 49 chars- last place must be saved for '\0'
      scanf("%s", word[i]);
      strlwr(word[i]);
   }
//for each word in the array make first char upper case
//toupeer takes in an int an returns an int for the int value of the char in upper case
//if you don't place the return instead of the lower- it would have no effect
//it is important to note that toupper is in ctype.h and must be included
   for (i = 0; i < n; i++)
 {
     word[i][0] = toupper(word[i][0]);
  }


   for (i = 0; i < n; i++)
       printf("%s\n", word[i]);

   return 0;
}
H.cohen
  • 517
  • 3
  • 9
  • *reconsider using `scanf` as it is an unsafe function* – which alternative would you suggest? – Swordfish May 18 '19 at 08:01
  • I would use gets(). But I also know that at beginner levels they ease up to it by using scanf() first as I was *required* to when I started. @Swordfish – H.cohen May 18 '19 at 08:05
  • 1
    *I would use gets()* – Wrong answer. [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) – Swordfish May 18 '19 at 08:14
  • It is not really- I would either make user aware of unexpected behavior if line is over n chars long. or if I want to make it extra safe use getchar() and limit the number of chars entered myself. A lot of functions used carelessly in c will have harmful results. in this case since there was no formatting in my opinion using scanf() is worse. thank god you are here to tell all of us off. @Swordfish – H.cohen May 18 '19 at 08:35
  • *I would either make user aware of unexpected behavior if line is over n chars long.* – Um. with `gets()` you can't!? Did you want to write `fgets()`? – Swordfish May 18 '19 at 08:39
  • long discussions of this sort are discouraged at the comment area as you well know, especially since they are no long about what I wrote in the answer given above and you have made no remarks presenting your idea of a better solution. If you want to continue this discussion with me please do so in the correct manner.@Swordfish – H.cohen May 18 '19 at 08:56
  • The better solution is in my answer above. – *especially since they are no long about what I wrote in the answer given above* – You tell in your answer that `scanf()` is unsafe and suggest `gets()` as "better" alternative. The discussion is right about that. But to be honest I am tired of discussing that. `scanf()` and `fgets()` are perfectly safe when used correctly. `gets()` is not and can't be no matter how it is used. – Swordfish May 18 '19 at 09:20