0

As stated in the title I am trying to find all lower-case letters that are not in a series of words. There are no upper-case letters, digits, punctuation, or special symbols.

I need help fixing my code. I am stuck and do not know where to go from here.

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

int main(void){
int letters[26];
char words[50];
int i = 0, b = 0;

printf("Enter your input : ");
scanf("%s", words);

for(i = 0; i < 26; i++){
  letters[i] = 0;
}

while(!feof(stdin)){

  for(b = 0; b < strlen(words) - 1; b++){
    letters[ words[b] - 'a']++;
    scanf("%s", words);
  }
}

  printf("\nMissing letters : %c ", b + 97);


  return 0;
}

My output is giving me some random letter that I do not know where it is coming from.

RollTide1234
  • 17
  • 1
  • 6
  • 1
    You realize that `letters[ words[b] - 'a' ]++` will increment some random memory location for any character that isn't a lowercase letter, right? Every space, newline, etc. All bets are off after that. But primarily, the value of b after the loop is just the length of the string words. Why would you expect it to contain a meaningful character? – Lee Daniel Crocker Feb 14 '18 at 22:45
  • @LeeDanielCrocker I see what you are talking about now, thanks – RollTide1234 Feb 14 '18 at 23:14
  • it's also better to store `strlen(words)` in a variable instead of calculating it again and again in the loop. And never use magic numbers like 65 or 97, no one knows what they mean, and they may mean different things in another charset. Use `'a'` or `'A'` – phuclv Feb 14 '18 at 23:58
  • 1
    Why are you reading words in each loop? By the way, [`while(!feof(stdin))` doesn't seem good](https://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) while it may not be completely wrong in this case. – MikeCAT Feb 15 '18 at 00:48
  • @MikeCAT yes I am aware that while(!feof(stdin)) doesn't work but I am supposed to use it as I have to end the string with control-d – RollTide1234 Feb 15 '18 at 01:18
  • 1
    The only time you need to use `feof()` is when you have already found that an I/O function has failed and you need to distinguish between an error (`ferror()` returns true) and EOF (`feof()` returns true). Otherwise, you don't need `feof()`. And if you type control-D at a terminal on a Unix system (under typical default settings), then that signals EOF by making `read()` return 0 bytes (unless there's some data already in the buffer, in which case that data is sent even before the enter key is pressed. – Jonathan Leffler Feb 15 '18 at 06:45
  • 1
    Note that the initial `scanf("%s", words)` skips leading white space and then only reads a single word terminated by white space (newline, blank, etc). – Jonathan Leffler Feb 15 '18 at 06:46
  • for ease of readability and understanding: consistently indent the code. indent after EVERY opening brace '{'. unindent before EVERY closing brace '}'. Suggest each indent level be 4 spaces – user3629249 Feb 15 '18 at 20:21

2 Answers2

0

Here is a working first implementation.

As well as the comments that have already been made, you should use functions wherever possible to separate out the functionality of the program into logical steps. Your main function should then just call the appropriate functions in order to solve the problem. Each function should be something that is self contained and testable.

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

#define MAX_INPUT 20 /* Max input to read from user. */

char *readinput(void);
void find_missing_lower_case(char *, int);

int main()
{
    char *user_input = readinput();
    int len_input = strlen(user_input);

    printf("user input: %s\n", user_input);
    printf("len input: %d\n", len_input);

    find_missing_lower_case(user_input, len_input);

    /* Free the memory allocated for 'user_input'. */
    free(user_input);
    return 0;
}

char *readinput()
{
    char a;
    char *result = (char *) malloc(MAX_INPUT);

    int i;
    for(i = 0; i < MAX_INPUT; ++i)
    {
        scanf("%c", &a);
        if( a == '\n')
        {
            break;
        }
        *(result + i) = a;
    }

    *(result + i) = '\0';
    return result;
}

void find_missing_lower_case(char *input, int len_input)
{
    int a = 97;        /* ASCII value of 'a' */
    int z = 122;       /* ASCII value of 'z' */

    int lower_case_chars[26] = {0};  /* Initialise all to value of 0 */

    /* Scan through input and if a lower case char is found, set the
     * corresponding index of lower_case_chars to 1
     */
    for(int i = 0; i < len_input; i++)
    {
        char c = *(input + i);
        if(c >= a && c <= z)
        {
            lower_case_chars[c - a] = 1;
        }
    }

    /* Iterate through lower_case_chars and print any values that were not set
     * to 1 in the above for loop.
     */
    printf("Missing lower case characters:\n");
    for(int i = 0; i < 26; i++)
    {
        if(!lower_case_chars[i])
        {
            printf("%c ", i + a);
        }
    }
    printf("\n");
}
laker93
  • 498
  • 4
  • 9
0

I figured it out and this is the code I used.

int main(void)
{
int array[26];
char w;
int i=0;

for(i=0; i<26; i++) {
array[i]=0; }
printf("Enter your input: ");
scanf("%c", &w); 
while(!feof(stdin)) {
    array[w-97] = 1; 
scanf("%c", &w); }

printf("Missing letters: ");

for(i=0; i<26; i++) {
    if(array[i] == 0) {
        printf("%c ", i+97); }
        }
printf("\n");

return 0;
}
RollTide1234
  • 17
  • 1
  • 6