1

I am new at C and coding in general, so please bear with me.

I am trying to create a "Keyboard testing" program where a user must populate an array by entering 1-character values in each element. The contents of the array will then be sorted and a printf will show which keys were pressed most (according to how many of each character was used). I've researched for two days to no avail (Most solutions are for C++, not C). I am working in Visual Studios. Here is what I have so far:

#define _CRT_SECURE_NO_WARNINGS
#define PAUSE system("pause")
#define CLS system ("cls")
#define FLUSH flush()
#define MAXELEMENTS 25 
#include <stdio.h>
#include <stdlib.h>

// prototyped functions
int pressKeys(char keys);

main() {
  char keys[MAXELEMENTS];
  int x;

  pressKeys(&keys[MAXELEMENTS]);
  PAUSE;
}

// functions

int pressKeys(char keys) {
  printf("Enter characters: \n");
  scanf("%c", &keys); FLUSH;

  printf("You typed: %c\n", keys);

  return(0);
}

The output of this program seems to be the first character I typed in, so a part of it is working, though it only shows what is in keys[0].

How do I get it to store everything typed?
How do I get printf to output the complete array?
How would I then go about passing the array to the function that will sort the contents in the elements?

(As far as arguments go in both main and the function declaration).

3
  • Out of curiosity, do you have something against using C++ for this? Are you taking a course in specific C programming, or are you just trying to learn the original before learning about the sequels? Commented Dec 4, 2016 at 1:41
  • BTW &keys[MAXELEMENTS] is address of last element . (and It doesn't use :-) Commented Dec 4, 2016 at 1:43
  • Does the user type the enter key between other keys, at the end of input or not at all? Commented Dec 4, 2016 at 7:00

2 Answers 2

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

int getIndex(char data);
void sortData(char* data);
void flushConsole(void);

#define MAX_ELEMENTS 25

// This table is used for looking up an index
char charLookupTable[] = "abcdefghijklmnopqrstuvwxyz";    

int main(void)
{
  // Create a buffer to hold the user input & clear it out before using
  char buffer[MAX_ELEMENTS]; 
  memset(buffer, 0, sizeof(char) * MAX_ELEMENTS);

  // Create a table to hold the number of times each key has been pressed
  // this table will be 1 less than the size of character lookup table since
  // it doesn't have a NULL at the end
  int countPressArray[sizeof(charLookupTable) - 1];
  memset(countPressArray, 0, sizeof(countPressArray));

  // Get the user data and read it into a buffer
  printf("Enter characters: ");
  scanf("%s", buffer);

  // Sort the user input data
  sortData(buffer);

  // Now that the data is sorted let's see how many times a specific character was used
  int index = 0;
  while(buffer[index] != NULL)
  {
    // Get the index of the counter to increment
    int countPressIndex = getIndex(buffer[index]);

    // Now increment the count in the table for each key press
    countPressArray[countPressIndex]++;

    // Check the next character
    index++;
  }

  // Clear the console buffer
  flushConsole();

  // Print the sorted data
  printf("Your sorted data is: %s\n", buffer);

  // Hold the console window open
  printf("\nPress any key to continue...");
  getchar();  

  // Exit the program
  return 0;
}


// This function will sort the data in the array using 
// a simple bubble sort algorithm.
void sortData(char* data)
{
  for (int i = 0; ; i++)
  { 
    if (data[i] == NULL)
    {
      // Everything is now in order
      break;
    }

    for (int j = i + 1; ; j++)
    {  
      if (data[j] == NULL)
      {
        // All values have been compared look at the next value
        break;
      }

      if (data[i] > data[j])
      {
        // The values need to be swapped use a temporary value as a third hand 
        char temp = data[i];
        data[i] = data[j];
        data[j] = temp;
      }
    }
  }
}

// This function flushes the console
void flushConsole(void)
{
  while (getchar() != '\n');
}

// This function will return the index of the character that was pressed
int getIndex(char data)
{
  for (int i = 0; i < sizeof(charLookupTable) / sizeof(char); i++)
  {
    if (data == charLookupTable[i])
    {
      // We have found a match return the index of the character
      return i;
    }
  }

  // Couldn't find this character in the table return an error
  return 0xFF;
}

I have included answers to your questions and you should be able to run with what is provided see below for details:

  • How do I get it to store everything typed?

    1. First, you need to create a character buffer char buffer[MAX_ELEMENTS];.

    2. Next, you need to clear this buffer out since it is on the stack and has been initialized with garbage. You can do this by using memset(buffer, 0, sizeof(char) * MAX_ELEMENTS);.

    3. Lastly, you need to read the user data into this buffer using the string formatter and scanf.

      scanf("%s", buffer);.

  • How do I get printf to output the complete array?

    All you need to do is use printf with the string formatter and your buffer as follows:

    printf("Your sorted data is: %s\n", buffer);

  • How would I then go about passing the array to the function that will sort the contents in the elements?

    1. Create a sort function with a char pointer in the parameter list:

      void sortData(char* data);

    2. Next, pass the data buffer to the sort function as follows:

      sortData(buffer);

All you need now is to implement the counting for multiple instances of the same character!

Happy Programming!!


I am very glad I could help! I have updated my post with counting the number of times a character has been pressed. I also provide answers to your followup questions which I paraphrased to make it a little more clear.

  • What is the best way to count key presses?

    There are many ways this can be done but the most intuitive way to me is you need some kind of lookup table that can provide you an index.

    char charLookupTable[] = "abcdefghijklmnopqrstuvwxyz";

    Keep in mind this table is only for lowercase characters if you wanted numbers or uppercase you could add them to the beginning and end respectively. Now, create a function that will give you an index into this character string.

    int getIndex(char data);

    Lastly, just create another table of integers to keep track of counts.

    int countPressArray[sizeof(charLookupTable) - 1];

    Just use the index to increment the correct count value (i.e. index:0 = 'a', index:1 ='b', . . ., index:25 = 'z', etc...).

    countPressArray[countPressIndex]++;

  • Should I make a separate function for this?

    Yes, anytime you write code that is performing a specific task it is best to wrap it in a function. This allows the code to be more readable and easier to debug.

  • How do I print each element in the array with no repeats?

    I didn't provide this in my code example above but it is easy enough to implement. Now that we know how many times each key was pressed it is just a matter of checking to make sure it is not greater than 1 before you print.

Sign up to request clarification or add additional context in comments.

4 Comments

You were great help, Brandon! I tried to figure out how to count iterations from your code, but couldn't seem to figure it out. The closest I got (I used a for loop), was "NULL occurs less than "#" times", so something was wrong when trying to search the array. What is the easiest way for me to go about this? This time I need to find out how to print each element in the array, but with no repeats. Btw, should I make a separate function for this?
I am very glad I could help! I have updated my post to address your followup questions! Best Regards!
Thanks again for your help, Brandon! If it's ok, would you help me understand the code a little better? (Why you type what you type) For example, in this line: memset(buffer, 0, sizeof(char) * MAX_ELEMENTS); memset refers to memory set aside for its role, right? What does the 0 signify? Also, what is the role of NULL?
memset is used to initialize a piece of memory (stack or heap). It has 3 parameters 1.) A pointer to the memory location (i.e. buffer). 2.) The value to use for initialization (i.e. fill location with 0). 3.) The number of bytes to set from the start of the pointer (i.e. from the start of buffer intialize 25 bytes with 0). Since the stack and the heap can be initialized to anything when a variable is declared it is very important to put it in a defined state (clear it out). NULL just means as it says, it is nothing! This is used for pointers to initialize to and check against.
0

You should use fgets() to get a whole line. Or if you must use scanf(), note that %s means a string instead of %c which means one character.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.