Anagram of a string using pointer arithmatic - c

Here is the code to find the anagram for a string. I am using pointer array to do it but want to do it using pointer arithmetic.
#include <stdio.h>
int check_anagram(char [], char []);
int main()
{
char a[100], b[100];
int flag;
printf("Enter first string\n");
gets(a);
printf("Enter second string\n");
gets(b);
flag = check_anagram(a, b);
if (flag == 1)
printf("\"%s\" and \"%s\" are anagrams.\n", a, b);
else
printf("\"%s\" and \"%s\" are not anagrams.\n", a, b);
return 0;
}
int check_anagram(char a[], char b[])
{
int first[26] = {0}, second[26] = {0}, c = 0;
while (a[c] != '\0')
{
first[a[c]-'a']++;
c++;
}
c = 0;
while (b[c] != '\0')
{
second[b[c]-'a']++;
c++;
}
for (c = 0; c < 26; c++)
{
if (first[c] != second[c])
return 0;
}
return 1;
}
--> How to using pointer arithmetic and find it.
In the while loop :
while (a[c] != '\0')
{
first[a[c]-'a']++;
c++;
}
--> Can we modify it to below way so that it will work
while(*(a+c)!='\0')
{
*(first *(a+c)-'a')++;
c++;
}

first[a[c]-'a']++ = first[*(a+c)-'a']++ = (*(first+(*(a+c)-'a')))++

The usual way to process an array using pointers is by initializing a pointer to the beginning of the array, and then increment it, rather than doing pointer arithmetic to index from the beginning each time.
char *c = a;
while (*c != 0) {
first[*c - 'a']++;
c++;
}
If you need to use pointer arithmetic for first as well, then it would be:
(*(first + *c - 'a'))++

Related

Pure Pointer notation in C

I have this coding assignment where I have to use pure pointer notation only. I am pretty much finished with it but I just realized that I used an array. I am not allowed to do so, unless I change it into a pointer somehow. That's where I am slightly stuck.
This is my code.
#include <stdio.h>
#include <stdlib.h>
/* Function Prototypes */
int main();
void s1(char *random);
void s2(char *s2_input, int index);
void strfilter(char *random, char *s2_input, char replacement);
int main()
{
for(;;)
{
int s1_index = 41;
char s1_random[s1_index];
s1(s1_random);
printf("\ns1 = ");
puts(s1_random);
printf("s2 = ");
int s2_index = 21;
char s2_input[s2_index];
s2(s2_input, s2_index);
if(s2_input[1] == '\0')
{
printf("Size too small");
exit(0);
}
if(s2_input[21] != '\0' )
{
printf("Size too big");
exit(0);
}
printf("ch = ");
int replacement = getchar();
if(replacement == EOF)
break;
while(getchar() != '\n');
printf("\n");
strfilter(s1_random, s2_input, replacement);
printf("\ns1 filtered = ");
puts(s1_random);
printf("Do you wish to run again? Yes(Y), No(N) ");
int run = getchar();
// or include ctype.h and do:
// run == EOF || toupper(run) == 'N'
if(run == EOF || run == 'N' || run == 'n')
break;
while(getchar() != '\n');
}
}
void s1(char *random)
{
int limit = 0;
char characters;
while((characters = (('A' + (rand() % 26))))) /* random generator */
{
if(limit == 41)
{
*(random + 41 - 1) = '\0';
break;
}
*(random + limit) = characters;
limit++;
}
}
void s2(char *s2_input, int index)
{
char array[21] = "123456789012345678901"; /* populated array to make sure no random memory is made */
char input;
int count = 0;
int check = 0;
while((input = getchar() ))
{
if(input == '\n')
{
*(s2_input + count) = '\0';
break;
}
else if(input < 65 || input > 90)
{
printf("invalid input");
exit(0);
}
*(s2_input + count) = input;
count++;
}
index = count;
}
void strfilter(char *random, char *s2_input, char replacement) /* replacement function */
{
while(*s2_input)
{
char *temp = random;
while(*temp)
{
if(*temp == *s2_input)
*temp = replacement;
temp++;
}
s2_input++;
}
}
My issue is this part I am not sure how to edit this to not include an array, and still have it output the program in the same way.
if(s2_input[1] == '\0')
{
printf("Size too small");
exit(0);
}
if(s2_input[21] != '\0' )
{
printf("Size too big");
exit(0);
}
I tried to take the address of the array at a certain point, and then dereference it with a pointer, however that is still using a array. Which is what I am trying to avoid. Any help would be greatly appreciated!
s2_input[i] can be written as *(s2_input+i) where i is some index.
if ((s2_input[1]) == '\0')
is equivalent to:
if (*(s2 + 1) == '\0')
Which means to dereference the value at s2 (which is the location of the zeroth[0] element), and add one to it.
The same could be done for any other location.
Pointer notation and what is often referred to as Indexed notation (which uses the [ ] subscript operator) are entirely equivalent. Either notion provides the pointer address plus an offset from that pointer address. See C11 Standard - 6.5.2.1 Array subscripting That being array[offset] or *(array + offset)1
For example accessing the first element using *array is shorthand for *(array + 0) which is simply array[0] in indexed notation. The 0 being the offset (in elements of that type) from the original pointer address. (type controls pointer arithmetic)
So array[10] is simply *(array + 10). If array is type char, array[10] is 10-bytes after array address. If array is type int (where an int is 4-bytes), then array[10] is 40-bytes after array address (10-int).
For a 2D array, the notation for arr2d[1][2] would simply be *(arr2d[1] + 2) which expanded further is simply *(*(arr2d + 1) + 2).
So generally array[i] is *(array + i) and arr2d[i][j] is *(*(arr2d + i) + j).
footnotes:
It follows that array[offset] is equivalent to *(array + offset) is equivalent to offset[array].

c- finding how many times a character occurs in a string

#include <stdio.h>
#include <string.h>
#define SIZE 40
int main(void)
{
char buffer1[SIZE] = "computer program";
char *ptr;
int ch = 'p', j = 0, i;
for (i = 0; i<strlen(buffer1); i++)
{
ptr = strchr(buffer1[i], ch);
if (ptr != 0) j++;
printf(" %d ", j);
}
}
I want to count how many times a character occurs in a string.
In my program I chose the character 'p'.
I know Pascal, I am learning C now. In pascal is a function called Pos(x,y) which is searching for x in y. Is something familiar to this? I think what I used here is not.
The function signature of strchr is
char *strchr(const char *s, int c);
You need to pass a char* but you have passed a char. This is wrong.
You have used the strlen in loop - making it inefficient. Just calculate the length of the string once and then iterate over it.
char *t = buffer;
while(t!= NULL)
{
t = strchr(t, ch);
if( t ) {
t++;
occurences++;
}
}
And without using standard library functions you can simply loop over the char array.
size_t len = strlen(buffer);
for(size_t i = 0; i < len; i++){
if( ch == buffer[i]) occurences++;
}
Or alternatively without using strlen
char *p = buffer;
while(*p){
if( *p == ch ){
occurences++;
}
p++;
}
Or
for(char *p = buffer; *p; occurences += *p++ == ch);
Try this example :
int main()
{
char buffer1[1000] = "computer program";
char ch = 'p';
int i, frequency = 0;
for(i = 0; buffer1[i] != '\0'; ++i)
{
if(ch == buffer1[i])
++frequency;
}
printf("Frequency of %c = %d", ch, frequency);
return 0;
}

How to make a function call with an array of characters in C

This is a program which display the number of words in a string.
I manage to make a function call but gives me an error of "Arguments list syntax error".
Any answer would be a such great help.
#include<stdio.h>
int wordCount(char str[],int b);
main()
{
char str[100];
int b, d;
clrscr(); // clear the screen every compile and build
printf("Write your message: ");
gets(str); //reads the str[] which the user input
b = strlen(str); // run without the <string.h>
d = wordCount(str,b);
printf("No. of words: %d", d);
getch();
}
int count(str[],b) // Where the error points out
{
int i=0,word=0;
for (i = 0; i < b; i++)
{
if (str[i] != ' ' && str[i] != '\t')
{
word++;
while (str[i] != ' ' && str[i] != '\t')
{
i++;
}
}
}
return word;
}
You have to specify the type of your arguments in the function definition :
int count(str[],b){ ...
should become
int wordCount(char str[],int b){ ...
just like in your function declaration.
Plus, you have to specify the return type of main() -> int main()
Plus, you have to #include <string.h> to use strlen()
Here are the changes I made in your code, it will work now
#include<stdio.h>
int wordCount(char str[],int b);
main()
{
char str[100];
int b, d;
clrscr();
printf("Write your message: ");
gets(str);
b = strlen(str);
d = wordCount(str,b);
printf("No. of words: %d", d);
getch();
}
int wordCount(char str[],int b)
{
int i=0,word=0;
for (i = 0; i < b; i++)
{
if (str[i] != ' ' && str[i] != '\t')
{
word++;
while (str[i] != ' ' && str[i] != '\t')
{
i++;
}
}
}
return word;
}
In your code, you didn't typed the correct function name as you have declared and the type of parameter was not given either thats why it was giving you error.

How to append null terminator to end of the indexed char pointer

I ran the following code and it crashes with the while loop running forever. When I debugged this code, I found the problem at *(pointer+cnt)='\0'; the null character is never there. I don't know how to append the null terminator here so that the program doesn't crash.
#include <stdio.h>
#include <stdlib.h>
char* decimal_binary(int);
int main()
{
int n;
char *ptr=NULL;
printf("Enter the number\n");
scanf("%d",&n);
ptr=decimal_binary(n);
//printing out the characters
while(ptr!='\0')
{
printf("%c",*ptr);
ptr++;
}
free(ptr);
return 0;
}
char* decimal_binary(int n)
{
int c,d,cnt=0;
char *pointer=(char*)malloc(8+1);
if(pointer==NULL)
exit(EXIT_FAILURE);
for(c=7;c>=0;c--)
{
d=n>>c;
if(d&1)
*(pointer+cnt)=1+'0';
else
*(pointer+cnt)=0+'0';
cnt++;
}
//Null not getting added at the end of this sequence.Hence while loop in main runs forever.
*(pointer+cnt)='\0';
return pointer;
}
You've chosen to write:
while(ptr!='\0')
That's a funny way of writing:
while (ptr != 0)
or:
while (ptr != NULL)
where you intended to write:
while (*ptr != '\0')
The conventional way of writing *(pointer+cnt) is pointer[cnt].
You can't afford to free the incremented pointer; you must free what was returned by malloc() — or calloc() or realloc() or …
Preserve a copy of the value returned by binary_decimal() and free the copy (or increment the copy and free the value in ptr).
You can use either of the two binary_decimal() functions in the code below:
#include <stdio.h>
#include <stdlib.h>
char *decimal_binary(int);
int main(void)
{
int n;
char *ptr = NULL;
printf("Enter the number\n");
scanf("%d", &n);
ptr = decimal_binary(n);
char *cpy = ptr;
//printing out the characters
while (*ptr != '\0')
{
printf("%c", *ptr);
ptr++;
}
putchar('\n');
free(cpy);
return 0;
}
char *decimal_binary(int n)
{
int cnt = 0;
char *pointer = (char *)malloc(8 + 1);
if (pointer == NULL)
exit(EXIT_FAILURE);
for (int c = 7; c >= 0; c--)
{
int d = n >> c;
if (d & 1)
pointer[cnt] = 1 + '0';
else
pointer[cnt] = 0 + '0';
cnt++;
}
pointer[cnt] = '\0';
return pointer;
}
Or:
char *decimal_binary(int n)
{
int cnt = 0;
char *pointer = (char *)malloc(8 + 1);
if (pointer == NULL)
exit(EXIT_FAILURE);
for (int c = 7; c >= 0; c--)
pointer[cnt++] = ((n >> c) & 1) + '0';
pointer[cnt] = '\0';
return pointer;
}
This could be compressed still more (and even less readably):
char *decimal_binary(int n)
{
char *pointer = (char *)malloc(8 + 1);
if (pointer == NULL)
exit(EXIT_FAILURE);
for (int c = 7; c >= 0; c--)
pointer[7 - c] = ((n >> c) & 1) + '0';
pointer[8] = '\0';
return pointer;
}
And for a buffer of 9 bytes, you could perfectly well allocate a local variable in main() and pass the address to decimal_binary() so it does not need to use malloc() and the main() does not need to use free:
#include <stdio.h>
#include <stdlib.h>
void decimal_binary(int, char *);
int main(void)
{
int n;
char buffer[9];
char *ptr = buffer;
printf("Enter the number\n");
scanf("%d", &n);
decimal_binary(n, buffer);
while (*ptr != '\0')
{
printf("%c", *ptr);
ptr++;
}
putchar('\n');
return 0;
}
void decimal_binary(int n, char *pointer)
{
for (int c = 7; c >= 0; c--)
pointer[7 - c] = ((n >> c) & 1) + '0';
pointer[8] = '\0';
}

pointers to an array only print the first character?

Just started learning c. I'm confused with the pointers and arrays.
This is my main function.
int next_statement(char *a, int n);
void consume_char(char c);
int var_lib_check(char type,char var);
int
main(int argc, char *argv[]) {
char statement[MAX_LINE];
int statement_len;
char type[MAX_LINE];
char var[MAX_LINE];
/* Print the output header comment */
printf(OUTPUT_HEADER, argv[0]);
/* Loop through statements read on stdin */
while ((statement_len = next_statement(statement,MAX_LINE)) > 0) {
printf("%s\n",statement);
sscanf(statement,"%s %s",type,var);
var_lib_check(*type,*var);
}
return 0;
int
var_lib_check(char type,char var){
char var_library[MAX_VARS][MAX_LINE];
char new_var[MAX_LINE];
int num_of_var;
int z;
num_of_var = 0;
printf("%s and %s",&type,&var);
if (strcmp(&type,DOUBLE_TYPE)==0||strcmp(&type,INT_TYPE)==0||
strcmp(&type,RTRN_TYPE)==0){
for (z= 0; z < num_of_var; z++){
if (strcmp(var_library[z],&var) == 0){
sprintf(new_var,"x%d",z);
printf("%s %s",&type,new_var);
return z;
}
}
strcpy(var_library[num_of_var],&var);
num_of_var += 1;
sprintf(new_var,"%x%d",num_of_var);
printf("%s %s",&type,new_var);
}
return num_of_var;
}
This program reads the input and if it is either int or double ... it would replace it to be for e.g. int x0.
Why does it only print the first letter of the type and variable when it runs the function when it should print the whole string?
int
next_statement(char *a, int n) {
int c, i;
for (i=0; i < n && (c = getchar()) != EOF; i++) {
if (c == CHAR_SEMI) {
consume_char('\n');
break;
}
a[i] = c;
}
if (c == CHAR_SEMI) {
a[i] = '\0';
return i; /* index when ; was read, so the length of saved. */
}
else if (i >= n) {
printf("%s Line too long.\n", ERROR_PREFIX);
exit(EXIT_FAILURE);
}
return 0;
}
/* reads one char from stdin and errors if it is not what was
* expected, thereby "consuming" the given char.
*/
void
consume_char(char c) {
int x;
if ((x=getchar()) != c) {
printf("%s expected '%c' found '%c'.\n", ERROR_PREFIX, c, x);
exit(EXIT_FAILURE);
}
return;
You have the function definition as
int var_lib_check(char type,char var){
and you call it as
var_lib_check(*type,*var);
By doing this, you are only passing one character, and not the entire string to it.
You should change your function to
int var_lib_check(char *type,char *var)
and call it as
var_lib_check(type,var);
Now, you are passing the string to it, and you can work on it like a pointer.
It's because you are passing only the first char to var_lib_check(). You have to pass the array, so first fix this
var_lib_check(*type,*var);
make it
var_lib_check(type,var);
then fix the var_lib_check() function
int
var_lib_check(char *type, char *var)
{
char var_library[MAX_VARS][MAX_LINE];
char new_var[MAX_LINE];
int num_of_var;
int z;
num_of_var = 0;
printf("%s and %s", type, var); /* remove the & */
if (strcmp(type, DOUBLE_TYPE) == 0 || strcmp(type, INT_TYPE) == 0 || \
strcmp(type, RTRN_TYPE)==0)
{
for (z = 0 ; z < num_of_var ; z++)
{
if (strcmp(var_library[z], var) == 0)
{
sprintf(new_var, "x%d", z);
printf("%s %s", type, new_var);
return z;
}
}
strcpy(var_library[num_of_var], var);
num_of_var += 1;
sprintf(new_var, "%x%d", num_of_var);
printf("%s %s", type, new_var);
}
return num_of_var;
}
Most of the code invokes undefined behavior, because you pass the address to a char where a pointer to a string is expected.
A string consists of a sequence of non-nul bytes followed by a nul byte, since you where passing the address to just one byte, the functions, namely printf() and strcmp() where reading past the value of the passed variable.

Resources