IN operator in C - c

Can I use the "IN" operator in C?
For instance, in searching an array, can I say:
if(a in array[i])
{
printf("%d \n", array[i]);
}
In Python, we may say this.

There's no built-in C syntax that does this. You can write a function that does. Ie, if array[i] is an array of ints:
int in(int n, int* arr, int len) {
int i;
for (i = 0; i < len; ++i) {
if (arr[i] == n) {
return 1;
}
}
return 0;
}
In some contexts such a function might already exist in the standard library. As n.m pointed out, strchr finds a pointer to first occurence of a character in a character array, or else NULL, so you can do strchar(array[i], a) == NULL if array[i] is a character array.

No there's no in in C language.
If want, you can call a function passing the variable a to check if it is there in the array or not, using linear search(or binary depending on the data).
if(isKey(a,array)) // if(in(a,array))
{
}
int isKey(int a, int* array, int size)
{
// code to search element is present return 1 if present else 0
}
EDIT :- It was supposed to be a pointer mistake while . and edited for size.

Related

last number in a function array

I want to write a function where I have a given array and number N. The last occurrence of this number I want to return address. If said number cannot be found I want to use a NULL-pointer
Start of the code I've made:
int main(void) {
int n = 3;
int ary[6] = { 1,3,7,8,3,9 };
for (int i = 0; i <= 6; i++) {
if (ary[i] == 3) {
printf("%u\n", ary[i]);
}
}
return 0;
}
result in command prompt:
3
3
The biggest trouble I'm having is:
it prints all occurrences, but not the last occurrence as I want
I haven't used pointers much, so I don't understand how to use the NULL-pointer
I see many minor problems in your program:
If you want to make a function, make a function so your parameters and return types are explicit, instead of coding directly in the main.
C arrays, like in most languages, start the indexing at 0 so if there are N element the first has index 0, then the second has 1, etc... So the very last element (the Nth) has index N-1, so in your for loops, always have condition "i < size", not "i <= size" or ( "i <= size-1" if y'r a weirdo)
If you want to act only on the last occurence of something, don't act on every. Just save every new occurence to the same variable and then, when you're sure it was the last, act on it.
A final version of the function you describe would be:
int* lastOccurence(int n, int* arr, int size){
int* pos = NULL;
for(int i = 0; i < size; i++){
if(arr[i] == n){
pos = &arr[i]; //Should be equal to arr + i*sizeof(int)
}
}
return pos;
}
int main(void){
int n = 3;
int ary[6] = { 1,3,7,8,3,9 };
printf("%p\n", lastOccurence(3, ary, 6);
return 0;
}
Then I'll add that the NULL pointer is just 0, I mean there is literally the line "#define NULL 0" inside the runtime headers. It is just a convention that the memory address 0 doesn't exist and we use NULL instead of 0 for clarity, but it's exactly the same.
Bugs:
i <= 6 accesses the array out of bounds, change to i < 6.
printf("%u\n", ary[i]); prints the value, not the index.
You don't actually compare the value against n but against a hard-coded 3.
I think that you are looking for something like this:
#include <stdio.h>
int main(void)
{
int n = 3;
int ary[6] = { 1,3,7,8,3,9 };
int* last_index = NULL;
for (int i = 0; i < 6; i++) {
if (ary[i] == n) {
last_index = &ary[i];
}
}
if(last_index == NULL) {
printf("Number not found\n");
}
else {
printf("Last index: %d\n", (int)(last_index - ary));
}
return 0;
}
The pointer last_index points at the last found item, if any. By subtracting the array's base address last_index - ary we do pointer arithmetic and get the array item.
The cast to int is necessary to avoid a quirk where subtracting pointers in C actually gives the result in a large integer type called ptrdiff_t - beginners need not worry about that one, so just cast.
First of all, you will read from out of array range, since your array last element is 5, and you read up to 6, which can lead in segmentation faults. #Ludin is right saying that you should change
for (int i = 0; i <= 6; i++) // reads from 0 to 6 range! It is roughly equal to for (int i = 0; i == 6; i++)
to:
for (int i = 0; i < 6; i++) // reads from 0 to 5
The last occurrence of this number I want to return as address.
You are printing only value of 3, not address. To do so, you need to use & operator.
If said number cannot be found I want to use a NULL-pointer
I don't understand, where do you want to return nullpointer? Main function can't return nullpointer, it is contradictory to its definition. To do so, you need to place it in separate function, and then return NULL.
If you want to return last occurence, then I would iterate from the end of this array:
for (int i = 5; i > -1; i--) {
if (ary[i] == 3) {
printf("place in array: %u\n", i); // to print iterator
printf("place in memory: %p\n", &(ary[i])); // to print pointer
break; // if you want to print only last occurence in array and don't read ruther
}
else if (i == 0) {
printf("None occurences found");
}
}
If you want to return an address you need yo use a function instead of writing code in main
As you want to return the address of the last occurence, you should iterate the array from last element towards the first element instead of iterating from first towards last elements.
Below are 2 different implementations of such a function.
#include <stdio.h>
#include <assert.h>
int* f(int n, size_t sz, int a[])
{
assert(sz > 0 && a != NULL);
// Iterate the array from last element towards first element
int* p = a + sz;
do
{
--p;
if (*p == n) return p;
} while(p != a);
return NULL;
}
int* g(int n, size_t sz, int a[])
{
assert(sz > 0 && a != NULL);
// Iterate the array from last element towards first element
size_t i = sz;
do
{
--i;
if (a[i] == n) return &a[i];
} while (i > 0);
return NULL;
}
int main(void)
{
int n = 3;
int ary[] = { 1,3,7,8,3,9 };
size_t elements = sizeof ary / sizeof ary[0];
int* p;
p = g(n, elements, ary); // or p = f(n, elements, ary);
if (p != NULL)
{
printf("Found at address %p - value %d\n", (void*)p, *p);
}
else
{
printf("Not found. The function returned %p\n", (void*)p);
}
return 0;
}
Working on the specified requirements in your question (i.e. a function that searches for the number and returns the address of its last occurrence, or NULL), the code below gives one way of fulfilling those. The comments included are intended to be self-explanatory.
#include <stdio.h>
// Note that an array, passed as an argument, is converted to a pointer (to the
// first element). We can change this in our function, because that pointer is
// passed BY VALUE (i.e. it's a copy), so it won't change the original
int* FindLast(int* arr, size_t length, int find)
{
int* answer = NULL; // The result pointer: set to NULL to start off with
for (size_t i = 0; i < length; ++i) { // Note the use of < rather than <=
if (*arr == find) {
answer = arr; // Found, so set our pointer to the ADDRESS of this element
// Note that, if multiple occurrences exist, the LAST one will be the answer
}
++arr; // Move on to the next element's address
}
return answer;
}
int main(void)
{
int num = 3; // Number to find
int ary[6] = { 1,3,7,8,3,9 }; // array to search
size_t arrlen = sizeof(ary) / sizeof(ary[0]); // Classic way to get length of an array
int* result = FindLast(ary, arrlen, num); // Call the function!
if (result == NULL) { // No match was found ...
printf("No match was found in the array!\n");
}
else {
printf("The address of the last match found is %p.\n", (void*)result); // Show the address
printf("The element at that address is: %d\n", *result); // Just for a verification/check!
}
return 0;
}
Lots of answers so far. All very good answers, too, so I won't repeat the same commentary about array bounds, etc.
I will, however, take a different approach and state, "I want to use a NULL-pointer" is a silly prerequisite for this task serving only to muddle and complicate a very simple problem. "I want to use ..." is chopping off your nose to spite your face.
The KISS principle is to "Keep It Simple, St....!!" Those who will read/modify your code will appreciate your efforts far more than admiring you for making wrong decisions that makes their day worse.
Arrays are easy to conceive of in terms of indexing to reach each element. If you want to train in the use of pointers and NULL pointers, I suggest you explore "linked lists" and/or "binary trees". Those data structures are founded on the utility of pointers.
int main( void ) {
const int n = 3, ary[] = { 1, 3, 7, 8, 3, 9 };
size_t sz = sizeof ary/sizeof ary[0];
// search for the LAST match by starting at the end, not the beginning.
while( sz-- )
if( ary[ sz ] == n ) {
printf( "ary[ %sz ] = %d\n", sz, n );
return 0;
}
puts( "not found" );
return 1; // failed to find it.
}
Consider that the array to be searched is many megabytes. To find the LAST match, it makes sense to start at the tail, not the head of the array.
Simple...

What recursive function can I use to substitute the characters in a string by the greatest character on its right?

I got this exercise (it's not homework or an assignment, just practice) that asks for a program that replaces the characters in a string by the greatest character on the right using recursive functions, no loops allowed.
If I have a string acbcba the function has to return ccccba.
One thing I've tried with the loops for the string is this, to maybe try to turn it into a recursion if it worked:
void nextGreatest(char *str, int size)
{
int max_from_right = str[size-1];
str[size-1] = -1;
for(int i = size-2; i >= 0; i--)
{
int temp = str[i];
str[i] = max_from_right;
if(max_from_right < temp)
max_from_right = temp;
}
}
Output: cccba
I think the issue is that it doesn't count the characters that don't have to be replaced.
There was also another example using python I found and tried to change to C (MAX is a macro from here):
void nextGreatest(char *arr, int rev_i, int maxnum){
if (rev_i == strlen(arr) - 1){
arr[0] = maxnum;
return;
}
int i = strlen(arr) - 1 - rev_i;
arr[i], maxnum = maxnum, MAX(maxnum, arr[i]);
return nextGreatest(arr, rev_i + 1, maxnum);
}
Output: ~bccba
This is a simple problem of recursion. The idea is, you MUST cross once over the full string to detect what is the maximum and to keep the index the maximum occurred at, and a the second pass over the string to replace some characters at indexes less than the index of the maximum with the maximum you detected at the first loop. I wrote this code for you:
#include <stdio.h>
void
replace_max_char(char*s, char **index, char *max)
{
if (!*s) return;
if (*s>=*max)
*index = s, *max = *s;
replace_max_char(s+1, index, max);
if (s<*index)
*s=*max;
}
int
main(void)
{
char s[] = "acbcba", *index, max;
replace_max_char(s, &index, &max);
printf("%s\n", s);
return 0;
}
Notice the if (s<*index) after the recursive call of replace_max_char(s+1, index, max). When the recursion finishes, it will start executing the stacked if... and at that moment the maximum is known and also the index the maximum occurred at.
It does not need to be hard:
char nextGreatest(char *s)
{
char n;
if (!*s) return 0;
n = nextGreatest(s + 1);
return *s = MAX(*s, n);
}
If a character is \0 then we've reached the end of the string. Otherwise, we have more characters to the right, and we want the current character to be the greatest of its own value and all values to the right. But since we call the function in this order, you only will need to call it for its direct right neighbour, because it will in turn do the same first.
think on it as an induction.
first define the recursive function well
the function get an arr of chars and switch the letter to the greatest from right.(you can define whatever you want)
we will do the recursive on the length of the arr(we can call it n, same as induction)
base: n=0 , array with only null charecter, just return the arr.
step: lets say if we send arr with length n-1 the function will work so what we nees to do for n? we simply need to look ob the first letter and check what is greatest from right and switch to it.
lets look on example: for acbcba, if we call on smaller arr, cbcba, the return will be cccba(since we assume it works for n-1), now we need to solve for n, so now we have arr acccba, so we look on the first letter and aee what is greatest from it, and then return it.
now try to code it.

Design a Character Searching Function, While Forced to Use strchr

Background Information
I was recently approached by a friend who was given a homework problem to develop a searching algorithm. Before anyone asks, I did think of a solution! However, my solution is not what the teacher is asking for...
Anyway, this is an introductory C programming course where the students have been asked to write a search function called ch_search that is supposed to search an array of characters to determine how many times a specific character occurs. The constraints are what I don't understand...
Constraints:
The arguments are: array to search, character to search for, and length of the array being searched.
The function must use a for-loop.
The algorithm must use the strchr function.
Okay, so the first two constraints I can understand... but the 3rd constraint is what really gets me... I was initially thinking that we could just use a for-loop to iterate through the string from the beginning to the end, simply counting each instance of the character. When the student originally described the problem to me, I came up with (although incorrect) the solution:
Proposed Solution
int ch_search(char array_to_search[], char char_to_search_for, int array_size)
{
int count = 0;
for (int i = 0; i < array_size; i++)
{
// count each character instance
if (array_to_search[i] == char_to_search_for)
{
// keep incrementing the count
count++;
}
}
return count;
}
Then I was told that I had to specifically use the character position function (and apparently it has to be strchr and not strrchr so we can't start at the end I guess?)... I just don't see how that wouldn't be overcomplicating this. I don't see how that would help at all, especially counting from the beginning... Even strrchr might make a little more sense to me. Thoughts?
It's true that having the length of the array and having to use a for loop,
the most natural thing to do would be to iterate over every characters of the
source array. But you can also loop over the result of strchr like this:
int ch_search(char haystack[], char needle, int size)
{
int count = 0;
char *found;
for(; (found = strchr(haystack, needle)) != NULL; haystack = found + 1)
count++;
return count;
}
In this case you don't need the size of the array but the assignment doesn't say
that you have to use it. Obviously this solution requires the source to be '\0'-terminated.
I think the teacher wanted you to use strchr to navigate to the next occurrence of the char_to_search_for within a string:
int ch_search(char array_to_search[], char char_to_search_for, int array_size) {
int count = 0;
for (char *ptr = array_to_search ; ptr != &array_to_search[array_size] ; ptr++) {
ptr = strchr(ptr, char_to_search_for);
if (!ptr) {
break; // Character is not found
}
count++;
}
return count;
}
Note that array_to_search must be null-terminated in order to be used together with strchr solution above.
This sounds like your friend was given a trick question. The function gets an array of chars and the length of that array but is required to use strchr() even though that function only works on '\0' terminated strings (and there was not given any guaranty that the array is '\0' terminated).
You might thing that it would be fine to use strchr() on the array anyway and then compare the returned pointer to the given length of the array to check if it went past the end of the array. But there are two problems with that:
If strchr() searches past the end of the array, then you already have Undefined Behavior before getting to the check. The program might have crashed before returning from strchr(), the returned pointer might be some total garbage or you might get a pointer to an address a bit further in memory than the end of the array.
Even if the returned pointer is just to an address a bit further in memory than the end of the array, then there is the problem that comparing two pointers (or subtracting them to find the distance between the pointed addresses) is Undefined Behavior unless they're both pointing to parts of the same memory object (or one position past the end of the object). In this instance it means that checking if the returned pointer is within the bounds of the array is only defined behavior if the returned pointer is within the bounds of the array (or one past the end) making the check a bit useless.
The only solution to that is to make sure that strchr() is working with a '\0' terminated string. For example:
int ch_search(char array_to_search[], char char_to_search_for, int array_size)
{
char *buffer = malloc(array_size + 1);
// Add test here to check if malloc was succesful
strncpy(buffer, array_to_search, array_size);
buffer[array_size] = '\0';
int count = 0;
for (char *i = buffer; (i = strchr(i, char_to_search_for)) != NULL; i++) {
count++;
}
free(buffer);
return count;
}
strchr is a very convenient function to search for a char in a string.
Find and read more about strchr. This is my favorite function ever!
The C library function char *strchr(const char *str, int c) searches for the first occurrence of the character c (an unsigned char) in the string pointed to by the argument str.
Declaration
Following is the declaration for strchr() function.
char *strchr(const char *str, int c)
Parameters
str − This is the C string to be scanned.
c − This is the character to be searched in str.
Return value
Function returns a pointer to the first occurrence of the character c in the string str, or NULL if the character is not found.
Constraints:
1) The arguments are: array to search, character to search for, and
length of the array being searched.
This constrain gives the length of the array to be searched. The given array has to contain '\0' at some point. However the length of search search can be shorter and specified by the search_length.
Following compact solution takes this under account.
int ch_search(char array_to_search[], char char_to_search_for, int search_length)
{
int count = 0;
for(char *p = array_to_search; ;p++)
{
p = strchr(p, char_to_search_for);
if( p != NULL && (p - array_to_search < search_length) )
count++;
else
break;
}
return count;
}
Or equivalent ch_search2:
#include<stdio.h>
#include<string.h>
int ch_search(char array_to_search[], char char_to_search_for, int search_length)
{
int count = 0;
for(char *p = array_to_search; ;p++)
{
p = strchr(p, char_to_search_for);
if( p != NULL && (p - array_to_search < search_length) )
count++;
else
break;
}
return count;
}
// Your original function:
int ch_search1(char array_to_search[], char char_to_search_for, int array_size)
{
int count = 0;
for (int i = 0; i < array_size; i++){
// count each character instance
if (array_to_search[i] == char_to_search_for){
count++; // keep incrementing the count
}
}
return count;
}
int ch_search2(char array_to_search[], char char_to_search_for, int array_size)
{
int count = 0;
char *p = array_to_search;
for(;;)
{
p = strchr(p, char_to_search_for);
if( p != NULL )
{
if (p - array_to_search >= array_size) // we reached beyond
{
break;
}
else
{
count++;
p++;
}
}
else
break; // char not found
}
return count;
}
int main(void)
{
// the arr has to contain '\0' terminator but we can search within the specified length.
char arr[]={'1','1','2','2','1','1','3','3','3','1','4','4', '1','1','!','1','\0','1'};
char arr1[] = "zdxbab";
printf("count %d count %d \n",ch_search(arr , '1', 12),ch_search2(arr , '1', 12));
printf("count %d count %d \n",ch_search(arr1,'b',strlen(arr1)),ch_search2(arr1,'b',strlen(arr1)));
return 0;
}
Output:
count 5 count 5
count 2 count 2

Reading correctly from a 2D char array in a function

I can´t read from the char array
This is how I pass the string into my array for each test case and that works fine but passing the array is a problem. I looked it up here: Passing arrays and matrices to functions as pointers and pointers to pointers in C
I still get the warning that I compare between a pointer and an integer.
char klammern[MAX][STRING];
int i, test;
int ergebnis;
printf(" Test cases?:");
scanf("%d",&test);
getchar(); //catch Enter
for(i=0;i<test;i++)
{
fgets(klammern[i],30,stdin);
}
Here is how I pass the argument:
for(i=0;i<test;i++)
{
ergebnis = matching_brackets( klammern );
printf("%d ",ergebnis);
}
My function should count the numbers of brackets and return 1 if not all brackets are closed and 0 if everything is correct.
int matching_brackets(char (*klammern)[STRING])
{
int ergebnis, i;
int runde_klammern = 0;
for(i=0; *klammern[i] != '\n';i++)
{
if( *klammern[i] == '(')
{
runde_klammern++;
}
else if( *klammern[i] == ')')
{
runde_klammern--;
}
ergebnis = runde_klammern;
if ( ergebnis != 0)
{
return 1;
}
else
{
return 0 ;
}
While testing I saw that my for loop in the function read my array like this:
array [1][0]
array [2][0]
...
I want to loop the array like:
array[0][0]
array[0][1]
...
Edit: I do not get the compiler warning anymore after I fixed a typo in my function.
You have two problems, one is that your loop is wrong and the other is an operator precedence problem.
You should loop like e.g.
for (size_t i = 0; i < test; ++i)
{
for (size_t j = 0; klamern[i][j] != '\n'; ++j)
{
// Here `klamern[i][j]` is the current character
}
}
Note that you need to pass the test variable to the function as well.
The above loops also removes the second problem. (that *klamern[i] is seen by the compiler as *(klamern[i]) and not (*klamern)[i]).

How to find the length of an integer array passed as an argument in c?

I need to calculate the length of passed array in monkey method. How to do so, as input decays to a pointer inside monkey method...?
int monkey(int input1[])
{
//Write code here
}
Constraints:
1) You are not allowed to change the function signature.
int monkey(int input1[], size_t arraySize)
{
}
Passing the size of the array is the most usual method.
Alternatively you can do something like C strings, and add a sentinel value to the end of your array (max value, 0, -1, etc) and count the number of elements before this sentinel value.
There are no other alternatives I can think of.
In the general case, you don't. As it's just a pointer, information about the array is not available.
So you should pass in a size, or wrap it in a struct that contains the size.
Or as it's an array of int, you could use the first value in the array as the size.
Alternatively, depending on your use-case, you could zero-terminate (or else unambiguously mark the end of) the data in the array.
There is no way to do such thing in C. The definition of your function
int monkey(int input[])
is formally equivalent to
int monkey(int *input)
so you ALWAYS need to pass the length of your array as an additional parameter
Two options:
int array[10+1];
array[0] = 10;
// fill in the rest in array[1...10]
monkey(array);
// monkey() checks input1[0] to see how many data elements there are
and
int array[10+1];
array[0] = 10;
// fill in the rest in array[1...10]
monkey(array + 1);
// monkey() checks input1[-1] to see how many data elements there are
Alternatively, you can pass the size/count via a different channel, for example, a global variable, which you may guard with a critical section or a semaphore/lock if necessary.
When you pass the array to the function, you can store the length as the first element of the array:
int monkey(int input1[])
{
int len = input1[0];
for (int i = 1; i < len; ++i) {
// do something with the array
}
}
//...
int array[20];
array[0] = 20;
monkey(array);
An alternative method is to do it using pointer arithmetics instead, so that the function can treat the array as starting from 0:
int monkey(int input1[])
{
int len = *(input1 - 1);
for (int i = 0; i < len; ++i) {
// do something with the array
}
}
//...
int array[20];
array[0] = 19;
monkey(array + 1);
But it's the same thing really. The only advantage this has is guarding against mistakes like starting from 0 instead of 1. But then this means that you could forget to pass array + 1 when you call it. So meh.
int main()
{
int arr[] = { 62,34,4,4,4,3,2,-1 };
monkey(arr);
return 0;
}
int monkey(int input1[])
{
int n = 0;
while (a[n] != -1)
{
n++;
}
printf_s("Length of input1[] is: %d", n);
return n;
}
int monkey(int input1[])
{
//Write code here
}
int len = sizeof(input1)/sizeof(input1[0]);
OR
int len = sizeof(input1)/sizeof(int);
is WRONG..
IT will always give 2..as input1 is a LONG POINTER AND so size is 8,,and sizeof(int) is 4..
if you want to find the length there is 2 ways...
1) pass the length...
( you cannot i suppose )
2) if you have idea..about the input1 array...say ( TECH GIG competition )
try to find out the number contained in the undefined parts of the array..
say here i found out for the sample ..{1,2,3,4,5} => input1[6] => contains the number -9999
so just wrote a while loop to find the length
while(input1[len]!=-9999)
len++;
to find out that
input1[6] => contains the number -9999
i use in the answer
return input1[6]..to check
that -9999 was the answer
i just submitted the answer for TECH GIG competition

Resources