-1

I am trying to create a C code that takes an input string of maximum length 10 from the user and assigns each letter into different elements of an array of size 10. However, I cannot understand my results. My code:

char word1[9];
int i;

printf("Enter your first word: \n");
scanf("%s", &word1);
printf("your word is %s \n",word1);

for(i = 0; i < 10; i++)
    printf("%d ", word1[i]);
    
system("pause");

When I input the word "hello", the for loop shows me that each of the first 6 elements of the array word1 has been assigned the ASCII number equivalents of the letters h,e,l,l,o. Ideally, the last 4 elements should be 0 however they are not. output is [104 101 108 108 111 0 0 0 1 0]. Where is that 1 coming from? Similarly if I input "hi" the output is [104 105 0 24 -3 127 0 0 1 0]. What are these random numbers after 104 and 105 and why are they not 0?

For context, I am trying to build a simple code that would check if two input words are anagrams. My thought process is that 2 ASCII equivalent arrays would be produced which I can then sort in ascending order so I can compare each corresponding element.

Additional question: Why when I increase the 10 from i<10 in the for loop does output show more than 10 values? Since the array has 10 elements shouldn't it always show only 10 outputs?

Sorry if this is trivial, I am very new to C.

Gautham M
  • 4,816
  • 3
  • 15
  • 37
Sajidur
  • 45
  • 8
  • 1
    `word1` should have 11 elements if you want a 10-character string (and a NULL-terminator). Furthermore, even though you say this takes a maximum length of 10, you are not actually checking if that is true. Consider using `fgets` to limit the amount of bytes that get into the string. – mediocrevegetable1 Feb 17 '21 at 05:39

3 Answers3

1

You're getting the ASCII numbers because of this line:

printf("%d ", word1[i]);

You need to replace %d with %c – so the problem fixes. Still, there's a problem. When asking for input from the user, scanf() must be used to accept the limited number of characters:

char word[11]; // to get 10 chars + '\0' (null-terminator)
scanf("%10s", word);

You don't need to introduce an ampersand in the scanf() and use the (max length - 1) explicitly between % and s.

Lastly, iterating till the whole length of the array is a very bad idea. Considering iterating till the detection of a null-terminator. In short, replace:

for(i = 0; i < 10; i++)

with

while (word[i] != '\0')
Rohan Bari
  • 7,482
  • 3
  • 14
  • 34
1

Your biggest problems are:

  • incorrect use of scanf() adding & before word1 invoking undefined behavior. word1 is already a pointer due to array/pointer conversion. See: C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3)
  • You fail to use the field-width modifier to protect your array bounds allowing the user to exploit your code by entering more characters than your array can hold. Using scanf() with the "%s" conversion specifier without a field-width modifier to limit the input to the number of characters your array can hold is no safer than using gets(). See: Why gets() is so dangerous it should never be used!
  • You loop beyond the end of your array with your for loop if your array contains less than 9 character (which should be 11 to hold a 10 character string.) word1 (if properly read), is a nul-terminated string. You simply loop until you find the end-of-string (e.g. the '\0' character whose ASCII value is just plain-old 0). You don't loop over the max number of chars your array can hold -- they may hold values that are not set.

To correct the issues above, and more, you could do:

#include <stdio.h>

#define MAXCHR 10               /* if you need a constant, #define one (or more) */

int main (void) {
    
    char word1[MAXCHR + 1];     /* to treat chars as a string, you need +1 for \0 */
    int i;
    
    fputs ("Enter your first word: ", stdout);      /* no conversion, printf not needed */
    
    if (scanf ("%10s", word1) != 1) {               /* validate EVERY input, protect */
        puts ("EOF encountered on read of word1");  /* array bounds with field-width */
        return 0;
    }
    printf ("your word is: %s\n", word1);           /* output word1 */
    
    for (i = 0; word1[i]; i++)                      /* word1 is a string, loop to end */
        printf ("%c ", word1[i]);
    putchar ('\n');                                 /* tidy up with newline */
    
#if defined (_WIN32) || defined (_WIN64)
    system("pause");                                /* non-portable, only for windows */
#endif
}

(note: printf() is only needed for output if your output string contains a conversion, otherwise, puts(), or fputs() if end-of-line control is needed, are fine)

Example Use/Output

Basic input within the number of characters:

$ ./bin/word1
Enter your first word: bananas
your word is: bananas
b a n a n a s

Input of exactly the number of characters allowed:

$ ./bin/word1
Enter your first word: 1234567890
your word is: 1234567890
1 2 3 4 5 6 7 8 9 0

Input of twice as many characters as the array can hold as a string:

$ ./bin/word1
Enter your first word: 12345678901234567890
your word is: 1234567890
1 2 3 4 5 6 7 8 9 0

(note: no matter how many characters you attempt to input, only 10 plus the nul-terminating character will be stored. Be aware that any characters not read, remain in stdin unread -- just waiting to bite you on your next input. That is why input should be taken with fgets() or POSIX getline() so that the entire line of input is consumed. Regardless of which input function you use, you cannot use it correctly unless you check the return to determine if the input succeeded or failed.)

Look things over and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
0

The reason is, arrays are not initiated by a default value (like 0) in C, so when you input a string which does not cover whole the array, rest of elements don't have any default value and they have some garbage value from the memory. You can initiate the word array like this:

for(i = 0; i < 10; i++)
    word1[i] = 0;

PS: char word1[9]; creates 9 cells not 10. Also be aware that you should consider another cell for the \0 char which will indicate the string has ended. So in total you need 11 cells.

Amir MB
  • 3,233
  • 2
  • 10
  • 16