How to count Integer array elements like char based strlen() in C? - c

I would like to count the number of elements in an integer array(sized, like: array[1000]) after input without counting manually while inputting(using scanf() which is = number of arguments passed to scanf).Though int arrays are not null terminated as well as scanf() cannot be used like getchar() or gets() and no availale function like strlen() for int arrays,is it possible to write a C program to prompt the user to input as many numbers as he wishes and the program will count them(total arguments passed to scanf()) and print the maximum using arrays or pointers?

Without having a termination value, you will have to count the inputs as they are made. You could do this by defining a struct to hold the array. Your program does not know how many integers you will enter, and this code allocates more memory when the array is full, keeping track of the array size and elements used.
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_STEP 10 // increment in array size
typedef struct {
int maxlen; // capacity of array
int length; // elements used
int *array; // the array pointer
} istruct;
int main(void) {
istruct intarr = {0}; // empty array
int i;
printf ("Enter some integers:\n");
while (scanf("%d", &i) == 1) {
if (intarr.length >= intarr.maxlen) {
intarr.maxlen += ARRAY_STEP; // increase array size
intarr.array = realloc(intarr.array, intarr.maxlen * sizeof(int));
if (intarr.array == NULL) {
printf("Memory allocation error\n");
exit (1);
}
}
intarr.array[intarr.length++] = i;
}
printf ("You entered:\n");
for (i=0; i<intarr.length; i++)
printf ("%-10d", intarr.array[i]);
printf ("\n");
if (intarr.array)
free(intarr.array);
return 0;
}

strlen() iterates on the character array until the C string termination character (ASCII \0) is encountered. So it is COUNTING the elements. If you want to do that for an int array I guess you could also have a reserved 'terminator' value for your array, make room for it (allocate one more int in your array for the terminator) and implement your own int_array_len() similar to strlen. However, in your case counting the elements while inputting them seems like a much better way to go.

Smart vertion:
#include <stdio.h>
int main()
{
double a[100000],mx=0;
int i,j,c=0;
printf("Enter as many numbers as you wish . Press Ctrl+D or any character to stop inputting :\n");
/*for(i=0;i<100000;i++)
a[i]=0;*/
for(i=0;i<100000;i++)
{
if((scanf("%lf",&a[i]))==1)
c++;
//else break;
}
for(j=0;j<c;j++)
{
if(a[j]>mx) mx=a[j];
}
printf("You have inserted %d values and the maximum is:%g",c,mx);
return 0;
}

It's pretty simple.
just declare of your desired "initial size". And keep checking if input is a valid integer or not.
if((scanf("%d",&a[i]))==1) this would be true if and only if the input is a valid integer. hence the moment the input is not an int, it exits the loop. You can count the number of input values within the same loop and also the max values.
Here is the code:
#include <stdio.h>
#include<limits.h>
int main()
{
int a[100],max = INT_MIN;
int i,j,count=0;
printf("Start Entering the integers... Give any non-integer input to stop:\n");
for(i=0;i<100;i++)
{
if((scanf("%d",&a[i]))==1) {
count++;
if(a[i]>max) {
max = a[i];
}
}
else
break;
}
printf("number of input values: %d;\nThe maximum input value: %d",count,max);
return 0;
}

Related

How to count the number of same character in 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;
}

program outputs exit phrase instead of words stored in C

So I was working on an assignment for school, and had written up a variation of this code:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define MAX 100
// This program takes an input of strings and prints them out with a new line separating each one.
int main() {
char *WordArray[MAX]; //initializing variables
int i = 0;
int count = 0;
printf("enter up to 100 words, that are 20 characters maximum \n");
for (i = 0; i <100; i++){ //runs while there's less than 100 inputs
char Array[1];
scanf("%s",Array); //stores string in the array
if (strcmp(Array, "STOP") == 0) { //compares the string with stop, and if it is, it breaks out of the loop
break;
}
WordArray[i]=Array; //stores the string in the pointer array
}
printf("The output is\n");
for (count = 0; count<i; count++){ //counts up to the amount of words stored
printf("%s\n",WordArray[count]); //outputs each pointer string
}
}
and I noticed that the output was printing "STOP" instead of the values stored. Anyone have any answers to why and/or how to fix it? I know one of the methods is to switch to a 2D array instead of using pointers, but I'm still baffled as to why a program like this wouldn't work.
Your char Array[1]; isn't large enough to store any but an empty string. Also, when it works, every pointer will point to the same string, which will be the last entry you made. This makes some corrections where commented.
#include <stdio.h>
#include <stdlib.h> // instead of ctype.h
#include <string.h>
#define MAX 100
// This program takes an input of strings and prints them out with a new line separating each one.
int main() {
char *WordArray[MAX];
int i = 0;
int count = 0;
printf("enter up to 100 words, that are 20 characters maximum \n");
for (i = 0; i <100; i++){
char Array[21]; // increase size of array
scanf("%20s",Array); // limit entry length
if (strcmp(Array, "STOP") == 0) {
break;
}
WordArray[i] = strdup(Array); // allocate memory for and copy string
}
printf("The output is\n");
for (count = 0; count<i; count++){
printf("%s\n",WordArray[count]);
}
// free each string's memory
for (count = 0; count<i; count++){
free(WordArray[count]);
}
}
Program output:
enter up to 100 words, that are 20 characters maximum
one two three STOP
The output is
one
two
three
Edit: note that your code contains another undefined behaviour besides the too-short string char Array[1] which is that you dereference the pointer you stored in char *WordArray[MAX];. The scope of Array is inside the for loop, and theoretically ceases to exist after the loop completes, so the pointer you store is invalid. Here, the word entered is duplicated with strdup so that doesn't apply.

Why is my code outputting random numbers even though they are just counts?

I am starting to learn c. I am trying to make a code that will count the amount of a's and A's in a sentence but the code gives me random numbers every time it is executed even if it is the same sentence.
#include <stdio.h>
#include <string.h>
int main()
{
char words[10000000000];
int i;
int acount = 0;
int Acount = 0;
char A[0]="A";
char a[0]="a";
printf("Input your sentence to be counted.");
scanf("%s",words);
printf("%s",words);
for (i=0;i<=sizeof(words);i++)
{
if (words[i]==a[0]){
acount++;
}else if (words[i]==A[0]){
Acount++;
}
}
printf ("\nThe number of A's is %i. The number of a's is %i.",Acount,acount);
return 0;
}
Why is my code outputting random numbers even though they are just
counts?
Because you're counting uninitialized memory, given the code you posted.
This is uninitialized:
char words[10000000000];
(If 10 GB fits....)
This only sets the memory in words for the string that's read, plus the terminating '\0' character:
scanf("%s",words);
Assuming it works, anyway. You don't check the return value, so maybe it didn't work...
Now what will this loop do? (Ignoring the fact that int likely isn't big enough to index a 10GB array...)
for (i=0;i<=sizeof(words);i++)
{
if (words[i]==a[0]){
acount++;
}else if (words[i]==A[0]){
Acount++;
}
}
That loop will check every char in the array word and compare it to either 'A' or 'a'. Every last 10 billion or so of them, many if not most of them likely containing unknown values.
It will also check one char past the end of word. That's not good. This will not check past the end of word:
size_t i;
...
for (i=0;i<sizeof(words);i++)
{
if (words[i]==a[0]){
acount++;
}else if (words[i]==A[0]){
Acount++;
}
}
Note the change to < instead of <=, and the use of size_t for i instead of int.
Even better, so you don't try counting random data:
size_t i;
...
for (i = 0; words[i]; i++) {
if (words[i] == a[0]) {
acount++;
} else if (words[i] == A[0]) {
Acount++;
}
}
Since a string ends in a '\0' char value, the loop will now end when words[i] has a zero value.

How to dynamically take user input and store it into an integer array

I have an integer array like int a[50];. Now I want to store values entered by the user in the integer array as integers.
The problem is that I don't know the number of elements the user is going to input and hence I am unable to traverse the entire array.
So is there any method for the user to input the values dynamically and store it in the integer array and display it.
For this take a input from user for number of element to have in an array. Then malloc that memory and store the inputs in the array.
You can use realloc and make a specific input as end of the input
int readinput(int *value)
{
int status;
//function returns 0 on conversion -1 if exit keywoard entered
return status;
}
int value, *table = NULL,size = 0;
while (!readinput(&value))
{
table = realloc(table, (size++ + 1) * sizeof(int));
if (table == NULL)
{
break;
}
table[size] = value;
}
example converting function you can find here:
How to get Integer and float input without `scanf()` in c? in my answer
This code should work well, you can change BUFFER_SIZE to whatever you want, after these steps array will realloc to arr size + BUFFER_SIZE.
#include <stdio.h>
#include <stdlib.h>
#define BUFFER_SIZE 50
int main(void)
{
int * userInputBuffer = malloc(sizeof(int) * BUFFER_SIZE);
int userInput;
int counter = 0;
int reallocCounter = 1;
while ((scanf(" %d", &userInput)) == 1)
{
if ((counter % BUFFER_SIZE) == 0)
{
userInputBuffer = realloc(userInputBuffer, (reallocCounter++ + 1) * BUFFER_SIZE * sizeof(int));
}
userInputBuffer[counter++] = userInput;
}
for (int i = 0; i < counter; i++)
{
printf("User input #%d: %d\n", i + 1, userInputBuffer[i]);
}
free(userInputBuffer);
return 0;
}
The following solution uses the scanf() function with %d as format specifier. The while loop checks the return value so that it can detect if the conversion was successful. If anything other than a valid number is inputted the loop will break. A valid number is also beginning with space but not with any other characters.
The memory is allocated with malloc() and will be reallocated with realloc() each time the user entered a number. Note that there is no error checking about the reallocation this should be done with a temporary pointer like here.
Further this code will reallocate for every single number. You could also reallocate in bigger steps to avoid reallocation on every input. But this only matters if there is much data. In this case the speed improvement wouldn't matter.
After the memory is no longer needed you have to use free().
The user can type:
1<Enter>
2<Enter>
3<Enter>
any characters<Enter>
and will get:
Numbers entered:
1 2 3
as output.
Code:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
size_t idx;
int number;
size_t count = 0;
int* numberArr = malloc(sizeof(*numberArr));
printf("Enter each number separated by <Enter>,\n"
"to abort type any other character that isn't a number!\n");
while (scanf("%d", &number) == 1)
{
numberArr = realloc(numberArr, (count + 1) * sizeof(*numberArr));
numberArr[count] = number;
count++;
}
printf("\nNumbers entered:\n");
for (idx = 0; idx < count; idx++)
{
printf("%d ", numberArr[idx]);
}
printf("\n");
free(numberArr);
return 0;
}

Scan String Input for each testcase in C

the objective of my question is very simple. The first input that I get from the user is n (number of test cases). For each test case, the program will scan a string input from the user. And each of these strings I will process separately.
The question here is how can I get string inputs and process them separately in C language??? The idea is similar to the dictionary concept where we can have many words which are individual arrays inside one big array.
The program I have written so far:
#include <stdio.h>
#define max 100
int main (){
int n; // number of testcases
char str [100];
scanf ("%d\n",&n);
for (int i =0;i <n;i++){
scanf ("%s",&str [i]);
}
getchar ();
return 0;
}
Can someone suggest what should be done?
The input should be something like this:
Input 1:
3
Shoe
Horse
House
Input 2:
2
Flower
Bee
here 3 and 2 are the values of n, the number of test cases.
First of all, Don't be confused between "string" in C++ , and "Character Array" in C.
Since your question is based on C language, I will be answering according to that...
#include <stdio.h>
int main (){
int n; // number of testcases
char str [100][100] ; // many words , as individual arrays inside one big array
scanf ("%d\n",&n);
for (int i =0;i <n;i++){
scanf ("%s",str[i]); // since you are taking string , not character
}
// Now if you want to access i'th word you can do like
for(int i = 0 ; i < n; i++)
printf("%s\n" , str[i]);
getchar ();
return 0;
}
Now here instead of using a two-dimensional array, you can also use a one-dimensional array and separate two words by spaces, and store each word's starting position in some another array. (which is lot of implementation).
First of all yours is not C program, as you can't declare variable inside FOR loop in C, secondly have created a prototype using Pointer to Pointer, storing character array in matrix style datastructure, here is the code :-
#include <stdio.h>
#include <stdlib.h>
#define max 100
int main (){
int n,i; // number of testcases
char str [100];
char **strArray;
scanf ("%d",&n);
strArray = (char **) malloc(n);
for (i =0;i <n;i++){
(strArray)[i] = (char *) malloc(sizeof(char)*100);
scanf ("%s",(strArray)[i]);
}
for (i =0;i <n;i++){
printf("%s\n",(strArray)[i]);
free((strArray)[i]);
}
getchar ();
return 0;
}
#include <stdio.h>
#define MAX 100 // poorly named
int n=0; // number of testcases
char** strs=0;
void releaseMemory() // don't forget to release memory when done
{
int counter; // a better name
if (strs != 0)
{
for (counter=0; counter<n; counter++)
{
if (strs[counter] != 0)
free(strs[counter]);
}
free(strs);
}
}
int main ()
{
int counter; // a better name
scanf("%d\n",&n);
strs = (char**) calloc(n,sizeof(char*));
if (strs == 0)
{
printf("outer allocation failed!")
return -1;
}
for (counter=0; counter<n; counter++)
{
strs[counter] = (char*) malloc(MAX*sizeof(char));
if (strs[counter] == 0)
{
printf("allocate buffer %d failed!",counter)
releaseMemory();
return -1;
}
scanf("%s",&strs[counter]); // better hope the input is less than MAX!!
// N.B. - this doesn't limit input to one word, use validation to handle that
}
getchar();
// do whatever you need to with the data
releaseMemory();
return 0;
}

Resources