C - searching for a letter in word - c

I am trying to create a function which has two arguments, the word, and a letter to search in the word.
The word is actually an array where each letter is an element of the array, e.g. for the word "word", we have the following:
word = [w, o, r, d].
Therefore I have to compare each element of word[ ] to the letter, and if they match the function should return 1, otherwise 0.
The code is the following:
char ltt_srch(char word[], char ltt)//LINE 13
{
int len, i;
len = sizeof(word)/sizeof(word[0]);
for(i = 0; i < len; i++)
{
if(ltt == word[i])
{
return 1;
}
}
return 0;
}
I call ltt_srch in main using this code:
if(ltt_srch(word[len], ltt) == 0)//LINE 51
{
printf("Letter not found.\n");
}
but I get one warning and one note, specifically:
Line 13: [Note] Expected 'char *' but argument is of type 'char'
Line 51: [Warning] passing argument 1 of 'ltt_srch' makes pointer from integer without a cast

The problem is that you are passing word[len] instead of word as your first parameter. If you pass word[len] you will pass the character on the index len of word instead of word itself.
For example if word = "word" and len = 2 then word[len] == 'r'.
Solution:
if(ltt_srch(word, ltt) == 0) instead of if(ltt_srch(word[len], ltt) == 0).

This:
len = sizeof(word)/sizeof(word[0]);
is wrong. You cannot use sizeof inside a function to get the size of an array passed as an argument like that.
You meant:
const size_t len = strlen(word);
You need to search for the terminator, to work with general strings in C.
Also you're calling it wrong, this:
ltt_srch(word[len], ltt)
is subscripting into word which will yield a character, but you want to pass the array itself so it should be
ltt_srch(word, ltt)
Finally, the standard library has this function already, look up strchr():
int ltt_srch(const char *word, chr ltt)
{
return strchr(word, ltt) != NULL;
}

#include <stdio.h>
#include <stdlib.h>
int ltt_srch(char word[], char ltt);
int
main(void) {
char *word = "word";
char key = 'r';
if (ltt_srch(word, key)) {
printf("Letter found.\n");
} else {
printf("Letter not found.\n");
}
return 0;
}
int
ltt_srch(char word[], char ltt) {
int i;
for(i = 0; word[i] != '\0'; i++) {
if(ltt == word[i]) {
return 1;
}
}
return 0;
}

Related

C - How to check if unwanted character is in an array?

I have a question about string arrays.
I am trying to find a way to check if a string has an undesired character in it.
Tested array has to only contain one of these 8 options: {'A','a','C','c','G','g','T','t'}
All the white spaces are removed prior to this checking process.
If I have two arrays
A = {AGctcgtacgtacg}
B = {CGTAagctFcg}
A should pass the test and B should fail because it has 'F' in it.
I'm thinking of using a for loop to go over each element of the array and trying to check if the character is one of the options.
const char test[] = {'A','a','C','c','G','g','T','t'};
int l = strlen(A);
char A[] = {AGctcgtacgtacg}
char B[] = {CGTAagctFcg}
for (i = 0; i < l; i++){
if (A[i] is one of the characters in test){
do nothing... (keep checking)
}
else{
break;
printf("Error: the array contains unwanted character.");
exit(1);
}
}
You can use standard C function strspn declared in header <string.h> to check whether a string contains only valid characters.
For example
#include <stdio.h>
#include <string.h>
int main( void )
{
const char *test = "AaCcGgTt";
char A[] = "AGctcgtacgtacg";
char B[] = "CGTAagctFcg";
if (A[strspn(A, test)] == '\0')
{
puts("Array A has valid characters");
}
else
{
puts("Array A has invalid characters");
}
if (B[strspn(B, test)] == '\0')
{
puts("Array B has valid characters");
}
else
{
puts("Array B has invalid characters");
}
}
The program output is
Array A has valid characters
Array B has invalid characters
If you need to know also the position of the first invalid character then you can write for example
#include <stdio.h>
#include <string.h>
int main()
{
const char *test = "AaCcGgTt";
char A[] = "AGctcgtacgtacg";
char B[] = "CGTAagctFcg";
size_t n;
if (A[n = strspn(A, test)] == '\0')
{
puts("Array A has valid characters");
}
else
{
puts("Array A has invalid characters");
printf("Invalid character is %c at position %zu\n", A[n], n);
}
if (B[n = strspn(B, test)] == '\0')
{
puts("Array B has valid characters");
}
else
{
puts("Array B has invalid characters");
printf("Invalid character is %c at position %zu\n", B[n], n);
}
}
The program output is
Array A has valid characters
Array B has invalid characters
Invalid character is F at position 8
Try using strchr(...) NOTE that test needs to be NUL terminated
const char test[] = {'A','a','C','c','G','g','T','t','\0'};
int l = strlen(A);
char A[] = {AGctcgtacgtacg}
char B[] = {CGTAagctFcg}
for (i = 0; i < l; i++){
if (strchr(test, A[i])){
do nothing... (keep checking)
}
else{
break;
printf("Error: the array contains unwanted character.");
exit(1);
}
}

Count number of consonants in a string

Another starter question.
int counterConstant;
int x;
for(x = 0; x<20; x++){
if("bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSVWXYZ".IndexOf(tempString[x]) >= 0){
counterConsonant++;
}
}
But I get an error:
"error: member reference base type 'char [42]' is not a structure or union"
Is there another way I could do this?
(I'm doing this inside a for that checks each char on the string.)
There are no objects in C, so there are no "methods" and you can't call IndexOf on a string literal. A string is nothing more than an array of characters in C.
With that in mind, let's see how you can actually loop over the characters of a string:
for (const char *p = tempString; *p != '\0'; ++p) {
/* loop body */
char c = *p; // *p is the current letter
}
This will create a pointer to the first element of the string, and then loop over all of the following characters, if you'd really prefer to use indexes, you could do
for (size_t i = 0, len = strlen(tempString); i < len; ++i) {
char c = tempString[i];
}
As far as checking each letter for consonant-ness, that you can write a helper function for
int is_consonant(char c) {
c = tolower(c); // #include <ctype.h>
if (!isalpha(c)) return 0; // if not a letter, return false
switch (c) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return 0;
default:
return 1;
}
}
now back to your loop, use this function to check each character.
int consonant_count = 0; // the =0 is important!
for (const char *p = tempString; *p != '\0'; ++p) {
if (is_consonant(*p)) {
++consonant_count;
}
}
If you don't initialize to 0, the initial value of consonant_count is unpredictable, so make sure you do.
If you are working on C (as it was specified in tags), strchr() method is used to search a char in a string, and strstr() is used to search a string in a string. We will use strchr() here because tempString[x] is a char. Also, don't forget to give your int variable an initial value. Try this code:
int main()
{
int counterConsonant = 0;
int x;
const char* tempString = "12345678901234567890";
for (x = 0; x<20; x++){
if (strchr("bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSVWXYZ", tempString[x]) != NULL){
counterConsonant++;
}
}
return 0;
}
C is a structured procedural language, so it doesn't have member functions/methods like a "true" object-oriented programming language such as C#. You could use a combination of strspn and strcspn like below to count sequences of consonants and non-consonant characters respectively, based on a predefined list of consonant characters:
#include <string.h>
size_t
count_consonants (const char *s)
{
size_t n;
size_t total = 0;
const char *consonants = "bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
/* While we haven't reached the end of the string,
execute the code in the body of the loop. */
while (*s != '\0')
{
/* Count the number of consonants starting at the current string position. */
n = strspn (s, consonants);
/* Add the number of consonants counted to
the total number of consonants found. */
total += n;
/* Advance the character pointer to the next character
that IS NOT a consonant, based on the number of consonants
stored in `n'. */
s += n;
/* Advance the character pointer to the next character
that IS a consonant (`strcspn' = skip the characters in
`s' that don't appear in `consonants'). */
s += strcspn (s, consonants);
}
return total;
}
char temp[20];
scanf("%s",temp);
int i,j, consonantsCounter=0;
char consonants[]={'b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z','B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','V','W','X','Y','Z'}
for(i=0;i<20;i++){
for(j=0;j<(sizeof consonants) / (sizeof consonants[0]);j++){
if(temp[i]==consonants[j]){
consonantsCounter++;
}
}
}

Reading Both Individual Characters of Strings and the Strings themselves Pointed to by a String Array

In the code below, I'm attempting to pass the string array 'char *wordArray[20]..." into the function above main that is intended to find all strings within wordArray that contain a user-input character, and print each such string. Function "findWords" is defined to expect a constant string array, its length and the user-input character because the array will be read-only. Following examples from the text I'm using, the bottom is a combination of methods for reading individual characters from a pointer to a string, and for reading strings from a pointer array.
#include <stdio.h>
#include <stddef.h>
#include <ctype.h>
int arrLength = 0; // Global variable dec. and initialization
void findWords ( const char *c[], int length, char letter ) {
size_t element = 0;
size_t count = 0;
for (element = 0; element < length; element++) {
for (count = 0; c[count] != '\0'; count++) {
if (c[count] == letter) {
printf("%s", c[element]);
}
else {
printf("%s", c[count]);
}
}
count++;
}
return;
} // End function findWords
int main (void) {
{ // Begin Problem 3
// step 1: printf "Problem 3"
puts("Hiya");
// step 2: create a string array of 3 pointers to strings containing at this point, random
words.
const char *wordArray[3] = { "cake", "foxtrot", "verimax" };
char usrInp; // Holds user-input letter.
// step 3: "Input a letter from the user."
// This do...while loop repeats until the user has entered either a lower- or uppercase
letter.
do {
puts("Please enter one lowercase letter - any you'd like\n"); // One string argument
calls for output function puts(); rather than printf();
usrInp = tolower ( getchar() );
} while ( isalpha (usrInp) == 0 );
findWords( wordArray, arrLength, usrInp );
} // End Problem 3
} // End function main
at findWords :
for (element = 0; element < length; element++) {
for (count = 0; c[element][count] != '\0'; count++) {
if (c[element][count] == letter) {
printf("%s\n", c[element]);
break;
}
}
}
at main :
arrLength = sizeof(wordArray)/sizeof(*wordArray);//arrLength = 3;
findWords( wordArray, arrLength, usrInp );
c[count] is char* which means you cannot compare it to a char. this pointer just holds the address to your current string. you need to traverse that string in order to check for letter.
In your code you need to change:
if (c[element][count] == letter)

To insert a substring in the given string:Error:15 [Warning] return makes integer from pointer without a cast

I wish to insert a substring in the main string from the given position c which is user entered but i am constantly getting this warning
Header File:
char insstr(char a[100],char b[100],int c){
int i,j,t;
while(b[i]!='\0'){
i++;
}
i=t;
i=0;
for(j=c;j<t;j++){
a[j]=b[i];
i++;
}
return a;
}
Main File:
#include<stdio.h>
#include"Q7.h"
main(){
char x[100],y[100],f;
printf("Enter the main string \n");
gets(x);
printf("Enter the substring \n");
gets(y);
printf("Enter the position from where you want to enter the string");
scanf("%d",f);
printf("%s",insstr(x,y,f));
}
Strings are usually represented as char arrays i.e. char[] or char*. Since you are returning a string from the function, the return type should be char*.
char* insstr(char a[100],char b[100],int c)
{
/* ... */
}
You don't initialize i in insstr() before using it. This:
int i,j,t;
while(b[i]!='\0')
{
i++;
}
Should be:
int i,j,t;
i = 0;
while(b[i] != '\0')
{
i++;
}
Or, instead of reinventing the wheel, you should be using strlen(b) instead.
This is just wrong:
i=t;
i=0;
You didn't initialize t, and you are assigning to i twice. You end up obliterating whatever was stored in i. And of course, you are overwriting the contents of a without taking care of what was there. You are not inserting a string into a, you are replacing part of it with b. And then of course, as mentioned in other comments and answers, the return value should be char *.
Why not something as simple as this:
char *insstr(char *a, char *b, int c)
{
size_t a_len = strlen(a);
size_t b_len = strlen(b);
strcat(a, b);
reverse(a+c, a_len-c);
reverse(a+a_len, strlen(b));
reverse(a+c, a_len-c+b_len);
return a;
}
Where reverse() is:
void reverse(char *str, size_t len)
{
size_t i = 0, j = len-1;
while (i < j)
{
char tmp = str[i];
str[i] = str[j];
str[j] = tmp;
i++;
j--;
}
}
The algorithm works by concatenating b to a and then doing the appropriate swaps to move b into the right spot. In general, you can think of a as a string that can be decomposed into two blocks, ac, where c is the block after the insertion point where b will stay. When you concatenate b to the original string, you get acb. Moving b to the spot before c is a matter of reversing c, reversing b, so that you get a c_r b_r, and then you reverse c_r b_r, getting bc - just what you wanted.
A small example of how to use it:
int main(void)
{
char str1[100] = "Hello!";
char str2[] = ", world";
insstr(str1, str2, 5);
printf("%s\n", str1);
return 0;
}
This prints:
Hello, world!
Remember that you must make sure that a is indeed large enough to hold b. In general, you should pass the size of a as an argument, so that you can take appropriate action if a is not big enough, or, alternatively, you can make your code ensure that insstr() is not called if a is not big enough.
And please don't use gets(). Always use fgets(). It doesn't hurt, it is not complex, and it shows that you care.
NOTE: this idea is generalized in the book Programming Pearls as an efficient and elegant way to implement string rotations (which is what you want after appending b). Off the top of my head, I think it is mentioned in the "Aha! Algorithms" column.
#include<stdio.h>
#include<stdlib.h>
int insstr ( char *str, char *ins, int at) {
int each;
int len = 0;
int lenstr = 0;
int lenins = 0;
while ( str[lenstr] != '\0') {
lenstr++;
}
while ( ins[lenins] != '\0') {
lenins++;
}
if ( at > lenstr) {
at = lenstr; // force at to length of str if needed
}
len = at;
for ( each = 0; each <= lenins; each++) {
str[len] = ins[each]; // append ins onto str
len++;
}
return 1; // return true
}
int main() {
char input[300];
char substr[300];
char position[300];
int insert;
int each;
printf ( "Enter a string.\n");
fgets ( input, sizeof ( input), stdin);
each = 0;
while ( input[each] != '\n') {
each++;
}
input[each] = '\0'; // remove new-line
printf ( "Enter sub-string.\n");
fgets ( substr, sizeof ( substr), stdin);
each = 0;
while ( substr[each] != '\n') {
each++;
}
substr[each] = '\0'; // remove new-line
printf ( "Enter position to insert sub-string.\n");
fgets ( position, sizeof ( position), stdin);
insert = atoi ( position); // make position an integer
if ( insstr ( input, substr, insert)) {
printf ( "%s\n", input); // insert is successful. print it.
}
return 0;
}

C program, Reversing an array

I am writing C program that reads input from the standard input a line of characters.Then output the line of characters in reverse order.
it doesn't print reversed array, instead it prints the regular array.
Can anyone help me?
What am I doing wrong?
main()
{
int count;
int MAX_SIZE = 20;
char c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
while(c != EOF)
{
count = 0;
c = getchar();
arr[count++] = c;
getReverse(revArr, arr);
printf("%s", revArr);
if (c == '\n')
{
printf("\n");
count = 0;
}
}
}
void getReverse(char dest[], char src[])
{
int i, j, n = sizeof(src);
for (i = n - 1, j = 0; i >= 0; i--)
{
j = 0;
dest[j] = src[i];
j++;
}
}
You have quite a few problems in there. The first is that there is no prototype in scope for getReverse() when you use it in main(). You should either provide a prototype or just move getReverse() to above main() so that main() knows about it.
The second is the fact that you're trying to reverse the string after every character being entered, and that your input method is not quite right (it checks an indeterminate c before ever getting a character). It would be better as something like this:
count = 0;
c = getchar();
while (c != EOF) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
That will get you a proper C string albeit one with a newline on the end, and even possibly a multi-line string, which doesn't match your specs ("reads input from the standard input a line of characters"). If you want a newline or file-end to terminate input, you can use this instead:
count = 0;
c = getchar();
while ((c != '\n') && (c != EOF)) {
arr[count++] = c;
c = getchar();
}
arr[count] = '\0';
And, on top of that, c should actually be an int, not a char, because it has to be able to store every possible character plus the EOF marker.
Your getReverse() function also has problems, mainly due to the fact it's not putting an end-string marker at the end of the array but also because it uses the wrong size (sizeof rather than strlen) and because it appears to re-initialise j every time through the loop. In any case, it can be greatly simplified:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0) {
dest[j] = src[i];
j++;
i--;
}
dest[j] = '\0';
}
or, once you're a proficient coder:
void getReverse (char *dest, char *src) {
int i = strlen(src) - 1, j = 0;
while (i >= 0)
dest[j++] = src[i--];
dest[j] = '\0';
}
If you need a main program which gives you reversed characters for each line, you can do that with something like this:
int main (void) {
int count;
int MAX_SIZE = 20;
int c;
char arr[MAX_SIZE];
char revArr[MAX_SIZE];
c = getchar();
count = 0;
while(c != EOF) {
if (c != '\n') {
arr[count++] = c;
c = getchar();
continue;
}
arr[count] = '\0';
getReverse(revArr, arr);
printf("'%s' => '%s'\n", arr, revArr);
count = 0;
c = getchar();
}
return 0;
}
which, on a sample run, shows:
pax> ./testprog
hello
'hello' => 'olleh'
goodbye
'goodbye' => 'eybdoog'
a man a plan a canal panama
'a man a plan a canal panama' => 'amanap lanac a nalp a nam a'
Your 'count' variable goes to 0 every time the while loop runs.
Count is initialised to 0 everytime the loop is entered
you are sending the array with each character for reversal which is not a very bright thing to do but won't create problems. Rather, first store all the characters in the array and send it once to the getreverse function after the array is complete.
sizeof(src) will not give the number of characters. How about you send i after the loop was terminated in main as a parameter too. Ofcourse there are many ways and various function but since it seems like you are in the initial stages, you can try up strlen and other such functions.
you have initialised j to 0 in the for loop but again, specifying it INSIDE the loop will initialise the value everytime its run from the top hence j ends up not incrmenting. So remore the j=0 and i=0 from INSIDE the loop since you only need to get it initialised once.
check this out
#include <stdio.h>
#include <ctype.h>
void getReverse(char dest[], char src[], int count);
int main()
{
// *always* initialize variables
int count = 0;
const int MaxLen = 20; // max length string, leave upper case names for MACROS
const int MaxSize = MaxLen + 1; // add one for ending \0
int c = '\0';
char arr[MaxSize] = {0};
char revArr[MaxSize] = {0};
// first collect characters to be reversed
// note that input is buffered so user could enter more than MAX_SIZE
do
{
c = fgetc(stdin);
if ( c != EOF && (isalpha(c) || isdigit(c))) // only consider "proper" characters
{
arr[count++] = (char)c;
}
}
while(c != EOF && c != '\n' && count < MaxLen); // EOF or Newline or MaxLen
getReverse( revArr, arr, count );
printf("%s\n", revArr);
return 0;
}
void getReverse(char dest[], char src[], int count)
{
int i = count - 1;
int j = 0;
while ( i > -1 )
{
dest[j++] = src[i--];
}
}
Dealing with strings is a rich source of bugs in C, because even simple operations like copying and modifying require thinking about issues of allocation and storage. This problem though can be simplified considerably by thinking of the input and output not as strings but as streams of characters, and relying on recursion and local storage to handle all allocation.
The following is a complete program that will read one line of standard input and print its reverse to standard output, with the length of the input limited only by the growth of the stack:
int florb (int c) { return c == '\n' ? c : putchar(florb(getchar())), c; }
main() { florb('-'); }
..or check this
#include <stdio.h>
#include <stdlib.h>
#define MAX 100
char *my_rev(const char *source);
int main(void)
{
char *stringA;
stringA = malloc(MAX); /* memory allocation for 100 characters */
if(stringA == NULL) /* if malloc returns NULL error msg is printed and program exits */
{
fprintf(stdout, "Out of memory error\n");
exit(1);
}
else
{
fprintf(stdout, "Type a string:\n");
fgets(stringA, MAX, stdin);
my_rev(stringA);
}
return 0;
}
char *my_rev(const char *source) /* const makes sure that function does not modify the value pointed to by source pointer */
{
int len = 0; /* first function calculates the length of the string */
while(*source != '\n') /* fgets preserves terminating newline, that's why \n is used instead of \0 */
{
len++;
*source++;
}
len--; /* length calculation includes newline, so length is subtracted by one */
*source--; /* pointer moved to point to last character instead of \n */
int b;
for(b = len; b >= 0; b--) /* for loop prints string in reverse order */
{
fprintf(stdout, "%c", *source);
len--;
*source--;
}
return;
}
Output looks like this:
Type a string:
writing about C programming
gnimmargorp C tuoba gnitirw

Resources