Counting characters in a string or file - c

I have the following code:
#include "stdafx.h"
#include "string.h"
#include "ctype.h"
/*selection sort*/
void swap(int A[], int j, int k)
{
int p = A[k];
int i;
for (i = 0; i < (k - j); i++)
{
A[k - i] = A[k - i - 1];
}
A[j] = p;
}
/*greatest number in an array*/
int max(int A[], int N, int k)
{
int max = k, i;
for (i = k; i < N; i++)
{
if (A[max] < A[i])
max = i;
}
return max;
}
int count_nonspace(const char* str)
{
int count = 0;
while(*str)
{
if(!isspace(*str++))
count++;
}
return count;
}
int _tmain(int argc, _TCHAR* argv[])
{
int a[256];
int i = 0, j = 0, count[256] = { 0 };
char string[100] = "Hello world";
for (i = 0; i < 100; i++)
{
for (j = 0; j<256; j++)
{
if (tolower(string[i]) == (j))
{
count[j]++;
}
}
}
for (j = 0; j<256; j++)
{
printf("\n%c -> %d \n", j, count[j]);
}
}
Program is calculating the number of apperances of each character in a string. Now it prints the number of apperances of all 256 characters, whereas i want it to prinf only the character with greatest number of apperances in a string. My idea was to use the selection sort method to the array with the nubmer of apperances, but this is not working, thus my question is how to printf only the character with the greatest number of apperances in the string?
If anybody would have doubts, this is NOT my homework question.
EDIT: I've just noticed that this code printf apperances of characters begining with "j" why is that?

I started typing this before the others showed up, so I'll post it anyway. This is probably nearly the most efficient (increasing efficiency would add some clutter) way of getting an answer, but it doesn't include code to ignore spaces, count characters without regard to case, etc (easy modifications).
most_frequent(const char * str)
{
unsigned counts[256];
unsigned char * cur;
unsigned pos, max;
/* set all counts to zero */
memset(counts, 0, sizeof(counts));
/* count occurences of each character */
for (cur = (unsigned char *)str; *cur; ++cur)
++counts[*cur];
/* find most frequent character */
for (max = 0, pos = 1; pos < 256; ++pos)
if ( counts[pos] > counts[max] )
max = pos;
printf("Character %c occurs %u times.\n", max, counts[max]);
}

Create an array with your char as index.
Keep incrementing the value in the array based on the characters read.
Now get the max out of the array which gives you the most occurring char in your input.
Code will look like:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void) {
char buf[100];
int i=0,max =0,t=0;
int a[256];
memset(a,0,sizeof(a));
fgets(buf,100,stdin);
buf[strlen(buf)-1] = '\0';
while(buf[i] != '\0')
{
a[(int)buf[i]]++;
i++;
}
i=0;
for(i=0;i<256;i++)
{
if(a[i] > max)
{
max = a[i];
t = i;
}
}
printf("The most occurring character is %c: Times: %d",t,max);
return 0;
}

Here is a solution for that, based on your own solution, and using qsort().
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
struct Frequency
{
int character;
int count;
};
int compare(const void *const lhs, const void *const rhs)
{
return ((struct Frequency *)rhs)->count - ((struct Frequency *)lhs)->count;
}
int main(int argc, char* argv[])
{
int i = 0, j = 0;
struct Frequency count[256];
memset(&count, 0, sizeof(count));
char string[100] = "Hello world";
for (i = 0 ; i < 100 ; i++)
{
for (j = 0 ; j < 256 ; j++)
{
count[j].character = j;
if (tolower(string[i]) == j)
{
count[j].count += 1;
}
}
}
qsort(count, sizeof(count) / sizeof(*count), sizeof(*count), compare);
/* skip the '\0' which was counted many times */
if (isprint(count[1].character))
printf("\nThe most popular character is: %c\n", count[1].character);
else
printf("\nThe most popular character is: \\%03x\n", count[1].character);
for (j = 0 ; j < 256 ; j++)
{
if (isprint(count[j].character))
printf("\n%c -> %d \n", count[j].character, count[j].count);
else
printf("\n\\%03x -> %d \n", count[j].character, count[j].count);
}
}
notice that the '\0' is set for all the remainig bytes in
char string[100] = "Hello world";
so the count of '\0' will be the highest.
You could use strlen() to skip '\0', in the counting loop, but don't
for (i = 0 ; i < strlen(string) ; ++i) ...
do it this way
size_t length = strlen(string);
for (i = 0 ; i < length ; ++i) ...

Related

Unique character count function does not take into consideration all lines (C)

My goal is to write a function, that calculates the number of all the unique characters from a redirected text file (meaning until EOF is reached). The code I wrote:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define ASCII_VALS 128
int strLen (char inp[])
{
int len = 0;
for(int i = 0; inp[i] != '\0'; i++){
len++;
}
return len;
}
int countUniqueChars (char inp[])
{
int everyCharValArr[ASCII_VALS] = {0};
int i, j = 0;
for(i = 0; i < strLen(inp); i++){
int convToInt = inp[i] - '0';
everyCharValArr[convToInt] = 1;
}
for (i = 0; i < ASCII_VALS; i++) {
j += everyCharValArr[i];
}
return j;
}
works for one string entered via scanf() like so:
int main ()
{
char inp[100];
printf("Enter a string: \n");
scanf("%99s", inp);
printf("%d\n", countUniqueChars(inp));
return 0;
}
But after I change the main function to read a redirected text file, like so:
int main ()
{
char inp[100];
int total = 0;
while(fgets(inp, 100, stdin)){
total += countUniqueChars(inp);
}
printf("%d\n", total);
return 0;
}
and runinng the program (./binary <input.txt) on a input.txt file with contents below:
Toydolls
Flies
trees
rocks
things
the value becomes 26, which is correct (1. word = 6 unique chars, 2. word = 5 unique chars, 3. word = 4 unique chars, 4. word = 5, 5. word = 6 unique chars), but it obviously does not take into consideration chars that appear on more lines, which should not be counted as unique chars at all. My question is How do I fix the function to accomplish this?
Try something like that: Note that I've added a mechanism not to count a duplicate uppercase letter and its lower case letter as unique.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
#define ASCII_VALS 128
int everyCharValArr[ASCII_VALS] = {0};
int strLen (char inp[])
{
int len = 0;
for(int i = 0; inp[i] != '\0'; i++){
len++;
}
return len;
}
void FindUniqueChars (char inp[])
{
int i;
for(i = 0; i < strLen(inp); i++){
if (inp[i] > ' ' && inp[i] != (char)127)
{
if (inp[i] >= 'A' && inp[i] <='Z')
{
inp[i] = tolower(inp[i]);
}
everyCharValArr[(int)inp[i]] = 1;
}
}
}
int CountUniqueChars( void )
{
int i, j = 0;
for (i = 0; i < ASCII_VALS; i++) {
j += everyCharValArr[i];
}
return j;
}
int main ()
{
char inp[100];
while(fgets(inp, 100, stdin)){
FindUniqueChars(inp);
}
printf("%d\n", CountUniqueChars());
return 0;
}

Every k-th digit cyclic problem using strings in C

Given some number in a form of string, I want to extract every k-th number from it. Then I go through the remaining string and extract every k-th number again. The thing I get as a result should be the number formed by these extracted ones(in a proper order). Example: 123456789, k = 3 --> 369485271
My algorithm is as follows: While the lenght of the string allows extracting every k-th number, I go through the string and store every k-th element in another string. Then I delete the extracted elements from the original string by tracking the proper index of an element and proceed forvard while the lenght of my str is sufficient.
I can't figure out what's the problem with my code. And maybe my approach isn't that good and there are some better/simpler ways of diong this?
#include <stdio.h>
#include <string.h>
void remove(char *str, unsigned int index) {
char *src;
for (src = str+index; *src != '\0'; *src = *(src+1),++src) ;
*src = '\0';
}
int main() {
char number[100];
char result[100];
int k;
printf("Enter a string: ");
scanf("%s",number);
printf("Enter a key: ");
scanf("%d",&k);
while (strlen(number)>k-1) {
for (int i = 0, p = 0; number[i] != '\0'; i++) {
if (i % k == (k-1)) {
result[p] = number[i];
p++;
}
}
for (int j = 0; number[j] != '\0'; j++){
if (j % k == (k-1)) {
remove(number, j);
j+=1; /*since the index was shifted due to removing an element*/
}
}
}
puts(result);
return 0;
}
You some issues:
You start writing your output from scratch again in each iteration of your while loop.
You do not handle the last digits
You do not treat the input as a cyclic input.
You do not terminate your output string.
remove is already a name of standard library function.
A shorter version could be this (untested):
#include <stdio.h>
#include <string.h>
void remove_digit(char *str, unsigned int index) {
char *src;
for (src = str+index; *src != '\0'; *src = *(src+1),++src)
;
}
int main() {
char number[100];
char result[100];
int k;
printf("Enter a string: ");
scanf("%s",number);
printf("Enter a key: ");
scanf("%d",&k);
int p = 0;
int i = 0;
int skip = k-1; // We remove 1 digit and skip k-1 digits
while (number[0] != 0) {
i = (i + skip) % strlen(number);
result[p] = number[i];
p++;
remove_digit(number, i);
}
number[p] = 0;
puts(result);
return 0;
}
The following code seems to be what you want:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void remove_(char *str, unsigned int index) {
char *src;
for (src = str+index; *src != '\0'; *src = *(src+1),++src) ;
*src = '\0';
}
int main(int argc, const char * argv[]) {
char number[100];
char result[100];
int tmp[100];
int k;
printf("Enter a string: ");
scanf("%s",number);
printf("Enter a key: ");
scanf("%d",&k);
int p = 0;
for (int tp = 0; strlen(number) > k-1; tp = 0) {
for (int i = 0; number[i] != '\0'; i++)
if (i % k == (k-1))result[p++] = number[i];
for (int j = 0; number[j] != '\0'; j++)
if (j % k == (k-1)) tmp[tp++] = j;
for (; tp; --tp) remove_(number, tmp[tp-1]);
}
// The newly added code
for (int index; strlen(number); ) {
index = (k-1) % strlen(number);
result[p++] = number[index];
remove_(number, index);
}
puts(result);
return 0;
}
The most important thing is that every while loop, you need to remove the elements in number at once. While ensuring the integrity of your original code, I made some changes. Unfortunately, the main idea of ​​the original code is wrong.
It should circulate from the tail (including the rest) to the head after one round. But I found that the function of the code you provided is that after each round, the next round starts from the 0th element of the head.
By the way, your algorithm is similar to the Josephus problem

Program to print all substrings of a given string

I am having trouble creating an algorithm that prints all substrings of a given string. This is my implementation now:
#include <stdio.h>
#include <string.h>
// Function to print all sub strings
void subString(char str[], int n)
{
// Pick starting point
for (int len = 1; len <= n; len++)
{
// Pick ending point
for (int i = 0; i <= n - len; i++)
{
// Print characters from current
// starting point to current ending
// point.
int j = i + len - 1;
for (int k = i; k <= j; k++) {
char data[n];
sprintf(data, "%d", str[k]);
printf("%s\n", data);
}
}
}
}
// Driver program to test above function
int main()
{
char str[] = "abc";
subString(str, strlen(str));
return 0;
}
My code is not converting integers to strings. Could someone help me figure out what's wrong?
The logic seems basically fine, but the formatting doesn't make much sense as this prints the digit values for each character and adds a newline for each print call. If you print the characters directly using %c formatting and only print a newline once you've emitted a full substring you'll have a more sensible result.
#include <stdio.h>
#include <string.h>
void subString(char *str, int n)
{
for (int len = 1; len <= n; len++)
{
for (int i = 0; i <= n - len; i++)
{
for (int j = i; j <= i + len - 1; j++)
{
putchar(str[j]);
}
puts("");
}
}
}
int main()
{
char str[] = "abc";
subString(str, strlen(str));
return 0;
}
Output:
a
b
c
ab
bc
abc
A little nitpick: I'd suggest calling this function printSubStrings since it produces a side effect. The name subString doesn't seem to match the contract particularly well.
You can also use the "%.*s" format to extract the substring chunk you want instead of the innermost loop:
void print_substrings(char *str, int n)
{
for (int len = 1; len <= n; len++)
{
for (int i = 0; i <= n - len; i++)
{
printf("%.*s\n", len, str + i);
}
}
}
#include<bits/stdc++.h>
using namespace std;
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
string str;
cin >> str;
for (int i = 0; i < str.size(); i++) {
for (int len = 1 ; len <= str.size() - i; len++)
{
cout << str.substr(i, len) << endl; // prints substring from starting index i till length len
}
}
return 0;
}
Input:
abcd
Output:
a
ab
abc
abcd
b
bc
bcd
c
cd
d

Continued Power Function Message

I keep getting the error message that my I have an undefined reference to the power function, but I'm not really sure where that is occurring or why my code is coming up with that error because I have used to power function before in this way. If anyone could help me figure out why it isn't working now I would really appreciate it.
#include "stdio.h"
#include "string.h" //Needed for strlen()
#include "math.h"
#define MAX_BITS 32
#define MAX_LENGTH 49
#define NUMBER_TWO 2
#define NUMBER_ONE 1
#define TERMINATOR '\0'
//Code to find the index of where the string ends
int last_index_of(char in_str[], char ch) {
for (int i = 0; i < MAX_LENGTH; i++) {
if(in_str[i] == ch) {
last_index_of == i;
}
}
return last_index_of;
}
//Code to find the start of the fractional aspect
void sub_string(char in_str[], char out_str[], int start, int end){
int i = 0;
while (i < 1) {
out_str[i] = in_str[start] + in_str[end-1];
i++;
}
}
int main()
{
//Declaration of variable
char input[MAX_LENGTH +1]; // +1 for '\0'
int number;
double exponent;
char output[MAX_BITS];
int fraction;
sub_string(input, output, 0, TERMINATOR);
//Input from the user
printf("Enter a floating point value in binary: ");
scanf("%s", input);
//Calculates the Decimal Part
for (int i = 0; i < last_index_of(input, TERMINATOR) ; i++) {
number = number + number + input[i];
}
printf("%d", number);
exponent = -1;
//Calculates the Fractional Part
for (int j = 0; j < last_index_of(input, TERMINATOR); j++) {
if (j == last_index_of) {
fraction = NUMBER_ONE/(pow(NUMBER_TWO, exponent));
printf("%d/n", fraction);
}
else {
fraction = NUMBER_ONE/(pow(NUMBER_TWO, exponent));
printf("%d + ", fraction);
exponent--;
}
}
return 0;
}
Some problems:
you need -lm option to linker to tell it where to find pow function
last_index_of is not correctly written, you use the function name as an internal variable, you can correct it this way:
//Code to find the index of where the string ends
int last_index_of(char in_str[], char ch) {
int ret = 0;
for (int i = 0; i < MAX_LENGTH; i++) {
if(in_str[i] == ch) {
ret = i;
}
}
return ret;
}
Note that you can replace your last_index_of() function by strlen()
as pointed in comment, sub_string() is not functionnal. A corrected version could be:
//Code to find the start of the fractional aspect
void sub_string(char in_str[], char out_str[], int start, int end){
int i = 0;
while (start != end) {
/* warning, bounds are still not tested...*/
out_str[i++] = in_str[start++];
}
out_str[i] = '\0'
}
Instead of calling last_index_of() in your exist for loop condition, you should take its value to re-use it:
for (int j = 0; j < last_index_of(input, TERMINATOR); j++) {
/* Error here: will never be TRUE */
if (j == last_index_of) {
/* ... */
}
else {
/* ... */
}
}
would become:
int last_index = last_index_of(input, TERMINATOR);
for (int j = 0; j < last_index; j++) {
if (j == last_index) {
/* ... */
}
else {
/* ... */
}
}
Another problem, you use number variable without initializing it, you should write int number = 0 instead of int number;
After that, there is also a problem with your logic.
You have some idea of what you want to do, but it is not clear in your code.
It seems that you want
the user to input some string in the form 10010.100111
to split this string into two parts 10010 and 100111
to convert the first part into integer part 10010 -> 18
to convert the second part into fractional part 100111 -> 0.609...
This decomposition may lead you to write this kind of code:
#include "stdio.h"
#include "string.h"
#define MAX_BITS 32
#define MAX_LENGTH 49
//Code to find the index of where the string ends
int last_index_of(char in_str[], char ch)
{
int ret = 0;
for (int i = 0; i < MAX_LENGTH; i++) {
if (in_str[i] == ch) {
ret = i;
}
}
return ret;
}
void sub_string(char in_str[], char out_str[], int start, int end)
{
int i = 0;
while (start != end) {
/* warning, bounds are still not tested... */
out_str[i++] = in_str[start++];
}
out_str[i] = '\0';
}
void split(char *input, char *first, char *second)
{
int idx = last_index_of(input, '.');
sub_string(input, first, 0, idx);
sub_string(input, second, idx + 1, strlen(input));
}
int main()
{
//Declaration of variable
char input[MAX_LENGTH + 1]; // +1 for '\0'
char first[MAX_BITS];
char second[MAX_BITS];
/* Input from the user */
printf("Enter a floating point value in binary: ");
scanf("%s", input);
/* split integer and fractionnal parts */
split(input, first, second);
/* decode integer part */
printf("integer part:\n");
for (int i = strlen(first) - 1, j = 1; i > -1; --i, j <<= 1) {
if (first[i] == '1') {
printf("%d ", j);
}
}
/* decode frac part */
printf("\nfractionnal part:\n");
for (int i = 0; i < strlen(second); ++i) {
if (second[i] == '1') {
printf("1/%d ", 2 << i);
}
}
return 0;
}

How to divide a string to substring and assign another substring?

I want to divide *eString to substrings. Substrings should be like that:
y_{1} = y_{1}y_{m+1}y_{2m+1}...
y_{2} = y_{2}y_{m+2}y_{2m+2}...
y_{m} = y_{m}y_{2m}y_{3m}...
where y is the element of *eString, and y is the substring of these elements.
For instance, if an user expects the key length which is 5, there should be (string size / 5) substrings. y_{1} has to contain the fist element of each divided substring. So, how can I implement this?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ALPHA 26
char *ReadFile(char *);
int main(int argc, char *argv[])
{
double frequency[ALPHA] = {0};
int c = 0;
int keylen = 0;
int counter = 0;
double indexofCoincidence = 0,total = 0;
const char *eString = ReadFile("cipher.txt");
int len = 0;
if (eString) {
puts("The encrypted text is:");
puts(eString);
puts("");
len = strlen(eString);
printf("The length of text is %d\n",len);
}
puts("");
while(eString[c]!= '\0'){
if(eString[c]>= 'a' && eString[c]<='z')
frequency[eString[c]-'a']++;
c++;
}
puts("The letters frequencies are :\n");
for(c=0; c<ALPHA;c++){
if(frequency[c]!= 0)
printf("%c : %.3f\t",c+'a',(frequency[c]/len));
total += (frequency[c]*(frequency[c]-1));
}
indexofCoincidence = (total/((len)*(len-1)));
printf("\n\nIndex of Coincidence : %.3f\n",indexofCoincidence);
if(indexofCoincidence < 0.060){
printf("\nIt looks like randomly.\n");
}
printf("Enter the your expected key length : ");
scanf("%d",keylen);
printf("\n");
char *y;
while(counter != keylen)
{
for(int i = 0; i<(len/keylen);i++){
y[counter] = *eString();
}
counter++
}
return EXIT_SUCCESS;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char *eString = "The quick brown fox jumps over the lazy dog";
int keylen = 5;
int len = strlen(eString);
int y_len = (len + keylen) / keylen + 1;
int i,j;
char **y = malloc(keylen * sizeof(*y));
for(i=0; i < keylen; ++i){
y[i] = malloc(y_len * sizeof(**y));
}
char *p = eString;
i = j = 0;
while(*p){
y[i % keylen][j] = *p++;
y[i % keylen][j+1] = 0;
if(++i % keylen == 0)
++j;
}
//check print & deallocate
for(i = 0; i < keylen; ++i){
printf("y_{%d} : %s\n", i+1, y[i]);
free(y[i]);
}
free(y);
return 0;
}

Resources