How to count the number of same character in C? - c

I'm writing a code a that prompts the user to enter a string
&
create a function that is a type void that prints out the character that was used the most
(As in where it appeared more than any other ones)
&
also shows the number of how many times it was in that string.
Therefore here is what I have so far...
#include <stdio.h>
#include <string.h>
/* frequent character in the string along with the length of the string (use strlen from string.h – this will require you to #include <string.h> at the top of your program).*/
/* Use array syntax (e.g. array[5]) to access the elements of your array.
* Write a program that prompts a user to input a string,
* accepts the string as input, and outputs the most
* You should implement a function called mostfrequent.
* The function prototype for mostfrequent is: void mostfrequent(int *counts, char *most_freq, int *qty_most_freq, int num_counts);
* Hint: Consider the integer value of the ASCII characters and how the offsets can be translated to ints.
* Assume the user inputs only the characters a through z (all lowercase, no spaces).
*/
void mostfrequent(int *counts, char *most_freq, int *qty_most_freq, int num_counts_)
{
int array[255] = {0}; // initialize all elements to 0
int i, index;
for(i = 0; most_freq[i] != 0; i++)
{
++array[most_freq[i]];
}
// Find the letter that was used the most
qty_most_freq = array[0];
for(i = 0; most_freq[i] != 0; i++)
{
if(array[most_freq[i]] > qty_most_freq)
{
qty_most_freq = array[most_freq[i]];
counts = i;
}
num_counts_++;
}
printf("The most frequent character was: '%c' with %d occurances \n", most_freq[index], counts);
printf("%d characters were used \n", num_counts_);
}
int main()
{
char array[5];
printf("Enter a string ");
scanf("%s", array);
int count = sizeof(array);
mostfrequent(count , array, 0, 0);
return 0;
}
I'm getting the wrong output too.
output:
Enter a string hello
The most frequent character was: 'h' with 2 occurances
5 characters were used
should be
The most frequent character was: 'l' with 2 occurances
5 characters were used

let's do it short (others will correct me if I write something wrong ^_^ )
you declare a int like this:
int var;
use it like this :
var = 3;
you declare a pointer like this :
int* pvar;
and use the pointed value like this:
*pvar = 3;
if you declared a variable and need to pass a pointer to it as function parameters, use the & operator like this :
functionA(&var);
or simply save its address in a pointer var :
pvar = &var;
that's the basics. I hope it will help...

The function prototype you are supposed to use seems to include at least one superfluous parameter. (you have the total character count available in main()). In order to find the most frequently appearing character (at least the 1st of the characters that occur that number of times), all you need to provide your function is:
the character string to be evaluated;
an array sized so that each element represents on in the range of values you want to find the most frequent (for ASCII characters 128 is fine, for all in the range of unsigned char, 256 will do); and finally
a pointer to return the index in your frequency array that holds the index to the most frequently used character (or the 1st character of a set if more than one are used that same number of times).
In your function, your goal is to loop over each character in your string. In the frequency array (that you have initialized all zero), you will map each character to an element in the frequency array and increment the value at that element each time the character is encountered. For example for "hello", you would increment:
frequency['h']++;
frequency['e']++;
frequency['l']++;
frequency['l']++;
frequency['o']++;
Above you can see when you are done, the element frequency['l']; will hold the value of 2. So when you are done you just loop over all elements in frequency and find the index for the element that holds the largest value.
if (frequency[i] > frequency[most])
most = i;
(which is also why you will get the first of all characters that appear that number of times. If you change to >= you will get the last of that set of characters. Also, in your character count you ignore the 6th character, the '\n', which is fine for single-line input, but for multi-line input you need to consider how you want to handle that)
In your case, putting it altogether, you could do something similar to:
#include <stdio.h>
#include <ctype.h>
enum { CHARS = 255, MAXC = 1024 }; /* constants used below */
void mostfrequent (const char *s, int *c, int *most)
{
for (; *s; s++) /* loop over each char, fill c, set most index */
if (isalpha (*s) && ++c[(int)*s] > c[*most])
*most = *s;
}
int main (void) {
char buf[MAXC];
int c[CHARS] = {0}, n = 0, ndx;
/* read all chars into buf up to MAXC-1 chars */
while (n < MAXC-1 && (buf[n] = getchar()) != '\n' && buf[n] != EOF)
n++;
buf[n] = 0; /* nul-terminate buf */
mostfrequent (buf, c, &ndx); /* fill c with most freq, set index */
printf ("most frequent char: %c (occurs %d times, %d chars used)\n",
ndx, c[ndx], n);
}
(note: by using isalpha() in the comparison it will handle both upper/lower case characters, you can adjust as desired by simply checking upper/lower case or just converting all characters to one case or another)
Example Use/Output
$ echo "hello" | ./bin/mostfreqchar3
most frequent char: l (occurs 2 times, 5 chars used)
(note: if you use "heello", you will still receive "most frequent char: e (occurs 2 times, 6 chars used)" due to 'e' being the first of two character that are seen the same number of times)
There are many ways to handle frequency problems, but in essence they all work in the same manner. With ASCII characters, you can capture both the most frequent character and the number of times it occurs in a single array of int and an int holding the index to where the max occurs. (you don't really need the index either -- it just save looping to find it each time it is needed).
For more complex types, you will generally use a simple struct to hold the count and the object. For example if you were looking for the most frequent word, you would generally use a struct such as:
struct wfreq {
char *word;
int count;
}
Then you simply use an array of struct wfreq in the same way you are using your array of int here. Look things over and let me know if you have further questions.

Here is what I came up with. I messed up with the pointers.
void mostfrequent(int *counts, char *most_freq, int *qty_most_freq, int num_counts_)
{
*qty_most_freq = counts[0];
*most_freq = 'a';
int i;
for(i = 0; i < num_counts_; i++)
{
if(counts[i] > *qty_most_freq)
{
*qty_most_freq = counts[i];
*most_freq = 'a' + i;
}
}
}
/* char string[80]
* read in string
* int counts[26]; // histogram
* zero counts (zero the array)
* look at each character in string and update the histogram
*/
int main()
{
int i;
int num_chars = 26;
int counts[num_chars];
char string[100];
/*zero out the counts array */
for(i = 0; i < num_chars; i++)
{
counts[i] = 0;
}
printf("Enter a string ");
scanf("%s", string);
for(i = 0; i < strlen(string); i++)
{
counts[(string[i] - 'a')]++;
}
int qty_most_freq;
char most_freq;
mostfrequent(counts , &most_freq, &qty_most_freq, num_chars);
printf("The most frequent character was: '%c' with %d occurances \n", most_freq, qty_most_freq);
printf("%d characters were used \n", strlen(string));
return 0;
}

Related

C programming. Function to generate a string of random letters using only arrays and then pointers

Im trying to code a program in C to generate a string containing random letters using only arrays first and then again using pointers. I've looked at many other questions but is not quite what I'm trying to accomplish. I can really use help please.
Function 1- Generates a string with random upper
case letter A-Z with 40 characters.
Function 2- Function to let user enter a string
with random upper case letter and a replacement character.
Function 3- Searches string1 from function 1 and replaces
occurences of any character from string 2 (user entered) with
replacement character.
OUTPUT EX.
String 1- "AABBCCDDEEFFGGHHABCDEFGH"
String 2- "BE"
Replacement char- "3"
Filtered string- AA33CCDD33FFGGHHA3CD3FGH.
This is what I have so far, Im not very good with arrays.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int s1 [41];
srand(time(NULL));
int i;
for (i = 0; i < 41; i++)
{
s1 [i] = rand();
}
return 0;
}
Any help will be appreciated.
Thanks alot.
#include <stdio.h>
#include <stdlib.h>
void rand_str(char* txt, size_t sz)
{
int i=sz-1;
while( i --> 0 )
{
txt[i] = 'A' + rand() % 26;
}
printf("Random Str: %.*s\n", sz+i, txt);
}
void fn2(char* tgt, size_t sz, char* repl )
{
puts("String 2: ");
fgets(tgt, sz, stdin);
puts("Replacement Char: ");
*repl = getchar();
}
void search_replace(char* txt, char* tgt, char repl)
{
while(*tgt != '\0')
{
while ((strchr(txt, *tgt) ? (tgt[strchr(txt, *tgt)-tgt] = repl) : 0) == repl);
tgt++;
}
}
int main(void)
{
char txt[41] = {0};
char tgt[40] = {0};
char repl;
rand_str(txt, sizeof(txt));
fn2(tgt, sizeof(tgt), &repl);
search_replace(txt, tgt, repl);
return !printf("Filtered String: %s\n", txt);
}
Please note that I did not compile any of this code. It might have some typo and/or runtime errors. The concept is correct though and you should understand the code first and not just copy it.
Function 1:
#include <stdlib.h> // Important! rand() function that generate random function is in that library!
//This function returns a pointer of an array (arr). In other words it returns the **address** of the first character of the array.
// Assuming arr is valid!
char* randomString(char* arr){
// This part does not REALLLYY matters it just makes sure the random will truly be random...
time_t t;
srand((unsigned) time(&t)); // Seeds the random function.
//------------------
//Looping the array assigning random letters:
int i = 0;
while(i<SIZE){
arr[i] = 'A'+(rand()%('Z'-'A'+1));// 'A' has a numerical value, we want the range from 'A' to 'Z' to be random. 'Z'-'A' is the range of letters (26) because its a modulu if the modulu was just 'Z'-'A' (26) it wouldnt print Z. 'Z' is the 26th letter, 26%26 is zero, it will not give 'Z' this is why I increased 'Z'-'A' by 1 so the modulu will include 'Z' as random latter.
i = i + 1;
}
arr[i] = 0;// String terminator also called NULL.
return "lol";
}
Function 2:
#include <string.h>
int replace(char* inputString, char* userInput,char replacement ){
/* e.g.
inputString = "ABSDSADASBBBAA";//Generate yourself... (Might want to user function 1)
userInput = "AB"; // You need to do the user input yourself...
replacement = 'D';
*/
int i = 0;
while(i<strlen(inputString)){
int j = 0;
while(j<strlen(userInput)){
if(inputString[i]==userInput[j]){
inputString[i] = replacement;
}
j = j+1;
}
i = i + 1;
}
}
Function 3:
int main(){
// Just use regular IO libraries to get user's input...
// Assuming you did that, I will hard code the values (you need to do the IO e.g. gets())
char str[SIZE];
randomString(str); // Requirement #1 reuse of function 1
char * userInput = "AB"; // You need to do the user input yourself...
char replacement = 'D';// You need to do the user input yourself...
replace(str, userInput, replacement)//Requirement #2
return 0;
}

function convert string to int - C

I want to scan in a string that can take at least 200 characters and then I want to convert the string to an int, so that I can print it with e.g. printf("%d", digit).
How can I write a function kinda like this I've written here
(this one does not work!):
int main()
{
char car[200];
int number;
int i,x;
int sum = 0;
printf("Write in number: \n");
scanf("%c", &car);
for (i=0; i<200; i++) {
if (car[i] != '\0') {
x = car[i]-'0';
sum = sum + x;
if (i != 0) {
sum = sum*10;
}
}
}
return 0;
}
first:
scanf("%c", &car);
from man scanf:
c
Matches a sequence of characters whose length is specified by the maximum field width (default 1); the next pointer
must be a pointer to char, and there must be enough
room for all the characters (no terminating null byte is added). The usual skip of leading white space is suppressed. To
skip white space first, use an explicit space
in the format.
So you're reading exactly one character, not a whole string.
Then, you rely on a terminating null byte being added, which isn't happening. Use %199s instead, leaving enough room for the terminating null byte.
Then, considering no int in this world should have enough space for numbers with 199 decimal digits, you should think about your 200 character buffer.
If your goal is not to write such a function for educational purposes, but because you need one:
int number;
scanf("%d", &number);
does exactly that: Read one number from the input, and place it in number.
scanf("%s", car);
You need to read a string %s not a single char %c. Also char array will decay to a pointer when passed as an argument, so you shouldn't use &char.
Here is the solution,Start from the end of the string because units place is from right to left then increment the units place to ten's place then 100 and so on.
#include<stdio.h>
#include<string.h>
int main()
{
char input[9];
int digit,number=0,i=1;
printf("Enter Number:\n");
scanf("%s",input);
digit=strlen(input)-1;
while(digit>=0)
{
number=number + i*(input[digit]-'0');
digit=digit-1;
i=i*10;
}
printf("%d",number);
return 0;
}
Close. Suggested changes below.
Use char car[200+1] to "take at least 200 characters".
Use "%200s" rather than "%c" to read a string rather than a char and to limit its input.
//int main()
int main(void) {
// char car[200];
char car[200+1];
int number;
int i,x;
int sum = 0;
printf("Write in number: \n");
// scanf("%c", &car);
scanf("%200s", car);
// for (i=0; i<200; i++) {
for (i=0; car[i]; i++) {
// if (car[i] != '\0'){
x = car[i]-'0';
// sum = sum + x;
sum = 10*sum + x;
// if (i != 0) { sum = sum*10; }
}
printf("%d\n", sum)
return 0;
}
Unless input is like "000000000000000000000000000123", 200 digits will certainly overflow sum.
To detect that
x = car[i]-'0';
if (sum >= INT_MAX/10 && (sum > INT_MAX/10 || x > INT_MAX%10)) {
x = INT_MAX;
// maybe set an error flag
break;
}
sum = 10*sum + x;
An int has an maximum value of INT_MAX from #include < limits.h>. It is at least 32767. Some platforms use 16-bit, 32-bit or 64-bit int Other ranges are possible. Let us assume a worst case of 128-bit. That would need about 39 decimal digits. Leaving room for a sign and terminating null character, suggest
char car[39+1+1];

C program Need help fixing my code for a word sort program

Hi I am still new to c and have been working on this word sort program for some time now. the guidelines are:
Write a program that sorts a series of words entered by the user. Assume that each word is no more than 20 characters long. Stop reading when the user enters an empty word. Store each word in a dynamically allocated string, using an array of pointers (use the read_line function). After all lines have been read sort the array. Then use a loop to print the words in sorted order.
The problem I seem to be having is that the program will accept words but when I enter the empty word it goes to a new line and nothing happens. An help or advice would be greatly appreciated. here is my code so far.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN 20
#define LIM 20
int read_line(char str[], int n);
void sort_str(char *list[], int n);
int alpha_first(char *list[], int min_sub, int max_sub);
int main(void)
{
char *list[LIM];
char *alpha[LIM];
char word_str[LEN];
int word, i, j, num_count = 0;
for(;;){
printf("Enter a word: ");
scanf("%s", &word);
if(word == NULL)
break;
else
read_line(word_str, LEN);
list[i] = malloc(strlen(word_str) + 1);
strcpy(list[i], word_str);
alpha[i] = list[i];
}
sort_str(alpha, i);
for(i = 0; i < num_count; ++i){
printf("Sorted: ");
puts(list[i]);
}
return (0);
}
int read_line(char str[], int n)
{
int ch, i = 0;
while ((ch = getchar()) != '\n')
if (i < n)
str[i++] = ch;
str[i] = '\0';
return i;
}
void sort_str(char *list[], int n)
{
int i, index_of_min;
char *temp;
for (i= 0; i < n - 1; ++i) {
index_of_min = alpha_first(list, i, n - 1);
if (index_of_min != i) {
temp = list[index_of_min];
list[index_of_min] = list[i];
list[i] = temp;
}
}
}
int alpha_first(char *list[], int min_sub, int max_sub){
int i, first;
first = min_sub;
for(i = min_sub + 1; i <= max_sub; ++i){
if(strcmp(list[i], list[first]) < 0){
first = i;
}
}
return (first);
}
Your logic flow is flawed. If a word is entered, the scanf() will eat it from stdin and store a null-terminated string at the address of the integer 'word'. Any more than 3/7 chars entered, (32/64 bit, allowing for the null terminator), will start corrupting the stack. read_line() will then only have the line terminator to read from stdin, (assuming the UB doesn't blow it up first).
The problem I seem to be having is that the program will accept words but when I enter the empty word it goes to a new line and nothing happens.
There are several problems with this:
char word_str[LEN];
int word, i, j, num_count = 0;
/* ... */
scanf("%s", &word);
if(word == NULL)
break;
First, scanf("%s", &word) scans whitespace-delimited strings, and to that end it skips leading whitespace, including newlines. You cannot read an "empty word" that way, though you can fail to read a word at all if the end of the input is reached (or an I/O error occurs) before any non-whitespace characters are scanned.
Second, you are passing an inappropriate pointer to scanf(). You should pass a pointer to a character array, but you instead pass a pointer to an int. It looks like maybe you wanted to scan into word_str instead of into word.
Third, your scanf() format does not protect against buffer overflow. You should provide a field width to limit how many characters can be scanned. Moreover, you need to be sure to leave room for a string terminator.
Fourth, you do not check the return value of scanf(). If it fails to match any characters to the field, then it will not store any. Since it returns the number of fields that were successfully scanned (or an error indicator), you can detect this condition.
One way to correct the scanf() and "empty word" test would be:
int result;
result = scanf("%*[ \t]%19[^ \t\n]", word_str);
if (result < 1) break;
(That assumes a fixed maximum word length of 19 to go with your declared array length of 20.) You have several additional problems in your larger code, large among them that read_line() attempts to read the same data you just read via scanf() (in fact, that function looks altogether pointless). Also, you never update num_count, and after calling sort_str() you lose track of the number of strings you've read by assigning a new value to variable i.
There may be other problems, too.

Write a `subString()` function

Write a function called subString() to extract a portion of a character string. The function should be called as follows
subString (source, start, count, result);
Where source is the character string from which you are extracting the substring, start is an index number into source indicating the first character of the substring, count is the number of characters to be extracted from the source string, and result is an array of characters that is to contain the extracted substring.
Here is what I have so far. I'm getting a weird result when I run the program
#include <stdio.h>
char substring (char source[], int start, int count, char result[])
{
int i;
source[start] = result [0]; // set the initial value of the result array to the value of the source array at the point of 'start'
for (i = 1; i <= count; i++, start++) { // keep adding to start until 'result' has obtained all the values it was supposed to get from the source array
source[start] = result[i];
}
result [count+1] = '\0'; // adds a null terminator to the end of the resultant string
return *result;
}
int main (void)
{
char source [] = "Any help would be appreciated. I dont know where I've gone wrong"; // define a generic string for the user to extract a string from
int start = 0, count = 0;
char result [255];
// allows for multiple different calls to be made without having to adjust the code every time
printf("%s",source);
printf("\n\nAt what point in the above statement should extracting begin? "); // assigns a starting point
scanf("%d", &start);
printf("\n\nHow many characters do you want to extract? "); // sets a number of characters to extract
scanf("%d", &count);
substring (source, start, count, result); // call the substring function
printf("\n\nThe resultant string, after extraction is: %s\n\n", substring); // print the result of the subString function
return 0;
}
This is an organized enumeration of problems with your code
You are passing the function name to printf(). Which indicates that it was a bad function name choice, you should pass result instead of substring.
You are returning only the first character of result in the substring() function.
Your function is using the uninitialized array result as the source string, which is incorrect, you need to copy the string from source to result instead.
This is a suggestion
char *substring (char *source, int start, int count, char *result)
{
int i;
for (i = 0 ; ((i < start) && (source[i] != '\0')) ; i++)
result[i] = source[i];
for ( ; source[i + count] != '\0' ; i++)
result[i] = source[i + count];
result[i] = '\0';
return result;
}
i think it's easy to understand what this function does.
VERY IMPORTANT: In c arrays are indexed from 0 to N - 1 so be careful with for loops.
I got it to work, using some of the help from above, but also with a good amount of my own thinking. Thanks for the help everybody
#include <stdio.h>
char *substring (char *source, int start, int count, char *result)
{
int i;
for (i = 0 ; i < (count) ; i++)
result[i] = source[i + start]; // after hitting start, as long as you're not at the end, the result should match the source
result[i] = '\0';
return result;
}
int main (void)
{
char source [] = "character"; // define a generic string for the user to extract a string from
int start = 0, count = 0;
char result [255];
printf("%s",source);
printf("\n\nAt what point in the above statement should extracting begin? "); // assigns a starting point
scanf("%d", &start);
printf("\n\nHow many characters do you want to extract? "); // sets a number of characters to extract
scanf("%d", &count);
substring (source, start, count, result);
printf("\n\nThe resultant string, after extraction is: %s\n\n", result); // calling result, not the whole function
return 0;
}

Finding the longest string from a list of ten strings in C?

I will have to take the input from user and find the longest input from those 10 strings..
#include<stdio.h>
#include<conio.h>
void main() {
char str[10][10]
printf("Enter strings:")
scanf("%s", str)
}
If I take the user input like this, would it store the strings in str two dimensional array? To find out the longest string first I would find the length of each strings and use max_length function to determine the longest string.
You do not need to store all of the strings, just the longest one entered so far.
Note that you do need to define a maximum length of string to avoid buffer overrun.
For example:
#define MAX_STRING_SIZE 1024
char last_entered_string[MAX_STRING_SIZE];
char longest_entered_string[MAX_STRING_SIZE] = ""; /* Must be initialized. */
scanf("%1023s", last_entered_string); /* Read one less to allow for
null terminator. */
Use a loop to accept the ten inputs and compare with the longest string. If the last entered string is longer then copy it into the longest string. As this is homework I'll not provide any further code.
No, it won't. You have to loop through and read all strings.
for(i=0;i<10;i++)
scanf("%s", str[i]);
Also, you are missing some semi-colons!
You can find the longest string put and save it for all the string received.
int main()
{
char *str = NULL;
char *compare;
printf("Enter strings:");
scanf("%s", compare);
if (strlen(str) < strlen(compare))
str = strdup(compare);
return(0);
}
And if you want to store all of users input (considering you can have just 10 string from the user)you can do this :
int main()
{
char **array;
char *str;
int x = 0;
int shortest;
array = malloc(sizeof(char*) * 10);
while (x < 10)
{
scanf("%s", str)
array[x] = strdup(str);
x++;
}
x = 0;
shortest = x;
while (x < 10)
{
if (strlen(array[x]) > strlen(shortest))
shortest = x;
x++;
}
return (0);
}
shortest will be the index of the longest string in your array.
I hope this will help you.
Store all input in an array, then do qsort() it on the array entries length and then take the first (or the last, depending on how you sorted) entry.
Ok, ok ... - this might be over-engineered ... ;-)
The program presented will take 10 input strings from the user and then finally print out the longest string and its length. It will not store any other input strings than the biggest one.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STR_LEN 1024
int main(int argc, char **argv){
char str_final[MAX_STR_LEN];
char str_temp[MAX_STR_LEN];
unsigned int i, j, len_str;
unsigned int num_string = 10;
unsigned int len_max = 0;
for (i=0; i<num_string; i++){
printf("Enter string number: %d\n", i);
gets(str_temp);
for (j=0; str_temp[j]; j++);
len_str = j;
if(len_str > len_max){
len_max = len_str;
memset(str_final, 0, MAX_STR_LEN);
memcpy(str_final, str_temp, len_str);
}else{
memset(str_temp, 0, MAX_STR_LEN);
}
}
printf("The biggest string is: %s\n", str_final);
printf("It's size is: %d\n", len_max);
exit(EXIT_SUCCESS);
}
I think what you can do is take a nested loop and search for a '\0' character in the row and run a counter simultaneously. as soon as you find a '\0' stop the counter and store the value of counter in a separate array . so now you will have a array of 10 integers.
Now search for smallest integer in the array and... Bingo!
The corresponding row will have the shortest string.
I know this approach is very raw but I think it will be helpful for people with only basic knowledge of C.

Resources