C Code to count how many letters in a word - c

I made simple code to count how many letters in a word, for some reason the variables letters is not consistent, here is the code
#include <stdio.h>
int main()
{
char str;
int slen(char *str)
{
int i;
int letters=0;
for(i=0;i<30;i++)
{
if((str[i]>='A'&&str[i]<='Z')||(str[i]>='a'&&str[i]<='z'))
letters++;
}
return letters;
}
printf("%d \n", slen("Word"));
}
The variable letter here prints 22.

Because of the < 30 condition in your for loop, your program goes past the "Word" string boundaries and starts calculating whatever's in memory right after that string.
Replace < 30 with < strlen(str) (you're going to need to #include <string.h>).
UPDATE: (kudos to #J...S (seee comments)) alternatively you can rewrite
for (i=0; i < 30; i++)
{
if((str[i]>='A'&&str[i]<='Z')||(str[i]>='a'&&str[i]<='z'))
letters++;
}
with
while (str != '\0') {
if ((*str >= 'A' && *str <= 'Z') || (*str >= 'a' && *str <= 'z')) {
letters++;
}
++str;
}
You could also use something like isalpha() instead of your if condition.
And, by the way, please use spaces to separate different parts of a line. Otherwise it's really hard to read. Thanks :)

The function should be declared/defined outside main().
Change this:
for(i=0;i<30;i++)
to this:
for(i = 0; i < strlen(str); i++)
because you want to iterate over the length of the string, and not more or less than its actual length.
In your case, "Word" had just 4 letters, and you iterated until i < 30 evaluated to false, invoking Undefined Behavior, since you would access memory that is out of bounds.
Putting everything together, we get:
#include <stdio.h>
#include <string.h>
int slen(char *str)
{
int letters=0;
for(unsigned int i=0;i<strlen(str);i++)
{
if((str[i]>='A'&&str[i]<='Z')||(str[i]>='a'&&str[i]<='z'))
letters++;
}
return letters;
}
int main()
{
printf("%d \n", slen("Word"));
}
Output:
4

You want this:
#include <stdio.h>
#include <string.h>
// declaring slen outside main (not using non standard GNU extension)
int slen(char *str)
{
int i;
int letters = 0;
int length = strlen(str); // using strlen, in order not to go beyond the end
// of the string
for (i = 0; i < length; i++) {
if ((str[i] >= 'A' && str[i] <= 'Z') || (str[i] >= 'a' && str[i] <= 'z'))
letters++;
}
return letters;
}
int main()
{
printf("%d \n", slen("Word123"));
}
Expected output here is 4 (4 lettres of "Word", not counting digits 1,2, and 3).
Slighly optimized version:
int slen(char *str)
{
int letters = 0;
for (int i = 0; ; i++) {
char c = str[i];
if (c == 0)
break;
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
letters++;
}
return letters;
}
and even better using isalpha from ctype.h:
#include <ctype.h>
...
int slen(char *str)
{
int letters = 0;
for (int i = 0; ; i++) {
int c = str[i]; // yes, int is correct, isalpha wants an int
if (c == 0)
break;
if (isalpha(c))
letters++;
}
return letters;
}

For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
Though some compilers can have their own language extensions nevertheless again according to the C Standard you may not define a function inside another function.
Also take into account that it is not necessary that Latin letters follow each other sequentially in a given character set. For example in the EBCDIC set some letters do not follow sequentially each other. There are embedded other symbols between letters.
So it is better to use standard C function isalpha declared in the header <ctype.h>.
Also the original string is not changed in the function. So it should be declared with the qualifier const.
And it is unclear why this magic number 30 is used in this loop within the function
for(i=0;i<30;i++)
Taking all this into account the program can look like
#include <stdio.h>
#include <ctype.h>
size_t letters_count( const char *s )
{
size_t count = 0;
for ( ; *s; ++s )
{
if ( isalpha( ( unsigned char )*s ) ) ++count;
}
return count;
}
#define N 100
int main(void)
{
char s[N];
printf( "Enter a statement: " );
fgets( s, sizeof( s ), stdin );
printf( "The statement contains %zu letters\n", letters_count( s ) );
return 0;
}
Its output might look like
Enter a statement: Hello TheErolley
The statement contains 15 letters

Related

counting individual characters in c

I’m working on a project called readability. the user input a text and the code should then use the coleman-liau function to determine the reading level. But in order to use this fuktion you have to determine the number of words, letters and sentences. Right now I’m busy counting the letters. So I wanted to ask how to count individual characters in c. right now this is my code:
int count_letters (string text)
{
int count_letters = 0;
int numb = 0;
for (int i = 0, n = strlen(text); i < n; i++)
{
if (text[i] != '')
{
count_letters++;
}
}
return count_letters;
}
You can either use isalpha() or "improvise".
This will work for the ASCII character set:
#include <stdio.h>
int count_letters(const char *str)
{
int count = 0, i = 0;
for (; str[i] != '\0'; i++)
{
if ((str[i] >= 'a' && str[i] <= 'z') || (str[i] >= 'A' && str[i] <= 'Z'))
{
/* any character within this range is either a lower or upper case letter */
count++;
}
}
return count;
}
int main(void)
{
char *str = "Hello\n world hello123#";
printf("%d\n", count_letters(str));
return 0;
}
or use isalpha(), also supports your current locale.
#include <ctype.h>
int count_letters(const char *str)
{
int count = 0, i = 0;
for (; str[i] != '\0'; i++)
{
if (isalpha((unsigned char)str[i]))
{
count++;
}
}
return count;
}
EDIT: As Andrew mentioned, to be pedantic, you better pass an unsigned char as argument to isalpha() to avoid any undefined behavior that might arise due to the signed type of str.

I am writing C function that convert lowercase char to upper case char with using ASCII but Output is not correct

Okay, So I start working on this, I have code below;
+I also have strlen("any string here") func that return len of any str in decimal just keep in your mind.
I take a lover case let's say a, then a will be equal some decimal num in ASCII table then I subtract 32 to get A.
Sadly this is not working, any idea for this?
Thank you for all help and your time!
int uppercase(char sent[]) {
for(int i=0; i <= strlen(sent); ++i) {
if(sent[i]>='a' && sent[i]<='z')
sent[i] -= 32;
}
The function is declared as having the return type int but returns nothing.
int uppercase(char sent[]) {
for(int i=0; i <= strlen(sent); ++i) {
if(sent[i]>='a' && sent[i]<='z')
sent[i] -= 32;
}
In general for a function that deals with strings the condition of the for loop should look at least like
for(int i=0; i < strlen(sent); ++i) {
Though it is better to write the loop like
for( size_t i = 0, n = strlen(sent); i < n; ++i ) {
However there is no great sense to use the function strlen in the function uppercase. Its call is redundant.
Pay attention to that you may not change a string literal. Any attempt to change a string literal results in undefined behavior.
From the C Standard (6.4.5 String literals)
7 It is unspecified whether these arrays are distinct provided their
elements have the appropriate values. If the program attempts to
modify such an array, the behavior is undefined.
Also it is better not to use the magic number 32.
The function can be written the following way as it is shown in the demonstrative program below.
#include <stdio.h>
char * uppercase( char *s )
{
for ( char *p = s; *p; ++p )
{
if ( 'a' <= *p && *p <= 'z' ) *p = *p & ~' ';
}
return s;
}
int main(void)
{
char s[] = "hello world!";
puts( s );
puts( uppercase( s ) );
return 0;
}
The program output is
hello world!
HELLO WORLD!
As for the function strlen then it is better to use another name for the function because it will conflict with the standard C function strlen. And the function itself can be defined the following way
size_t string_len( const char *s )
{
const char *p = s;
while ( *p ) ++p;
return p - s;
}
This code can help you
#include <stdio.h>
#include <string.h>
void uppercase(char T[],int k)
{
int i=0;
while(i<k)
{
if(T[i]>='a'&&T[i]<='z')
{
T[i]=(char)((int)T[i]-32);
}
i++;
}
i=0;
while(i<k)
{
printf("%c",T[i]);
i++;
}
printf("\n");
}
int main()
{
char T[]="good morning !";
int k=sizeof(T);
uppercase(T,k);
}
This one will work:
#include <stdio.h>
#include <string.h>
void uppercase(char sent[]) {
for (int i = 0; i < (int)strlen(sent); i++) {
if (sent[i] >= 'a' && sent[i] <= 'z') {
sent[i] -= 32;
}
}
}
int main(int argc, char* argv[]) {
if (argc > 1){
uppercase(argv[1]);
puts(argv[1]);
}
return 0;
}
It compiles without any errors and warnings (using clang), even with options -pedantic -Wall -Wextra.
/*
Parsing the string, then making the letters to uppercase.
*/
#include <stdio.h>
#include <limits.h>
int strlen(char s[]){ //String length function
int i;
for (i = 0; s[i] != '\0'; i++);
return i;
}
void uppercase(char sent[]) {
for(int i=0; i < strlen(sent); ++i) {
if(sent[i]>='a' && sent[i]<='z')
sent[i] += 32;
}
printf("%s", sent);
}
this is a whole tab of my whole work. when i try uppercase("hello world"); it giving me core dumped console problem.

Checking if string is only letters and spaces

I wrote this simple code to check if a string is letters and spaces only
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#define N 100
int checkString(char str1[]);
void main()
{
char str1[N];
scanf("%s", str1);
printf("%d",checkString(str1));
getch();
}
int checkString(char str1[])
{
int i, x=0, p;
p=strlen(str1);
for (i = 0; i < p ; i++)
{
if ((str1[i] >= 'a' && str1[i] <= 'z') || (str1[i] >= 'A' && str1[i] <= 'Z') || (str1[i] == ' '))
{
continue;
}
else{ return 0; }
}
return 1;
}
This works fine when I type something like :
hello asds //returns 1
hello1010 sasd // return 0
but if I type anything after space it returns 1, like this :
hello 1220 //returns 1
blabla 11sdws // returns 1
Can someone please tell me why?
The function can be written more simpler and correctly if to use standard C functions isalpha and isblank declared in header <ctype.h> For example
#include <ctype.h>
//...
int checkString( const char s[] )
{
unsigned char c;
while ( ( c = *s ) && ( isalpha( c ) || isblank( c ) ) ) ++s;
return *s == '\0';
}
If you want to check whether a string contains white spaces then instead of function isblank you should use function isspace.
Take into account that it is not a good idea to use statement continue in such simple loops. It is better to rewrite the loop without the continue statement.
And instead of function scanf it is better to use function fgets if you want to enter a sentence The function allows to enter several words as one string until the Enter will be pressed.
For example
fgets( str1, sizeof( str1 ), stdin );
Take into account that the function includes the new line character. So after entering a string you should remove this character. For example
size_t n = strlen( str1 );
if ( n != 0 && str1[n-1] == '\n' ) str1[n-1] = '\0';
You forgot about the numbers
int checkString(char str1[]) {
int i, x=0, p;
p=strlen(str1);
for (i = 0; i < p ; i++)
if ((str1[i] >= 'a' && str1[i] <= 'z') || (str1[i] >= 'A' && str1[i] <= 'Z') || (str1[i] == ' ') || (str1[i] >= '0' && str1[i] <= '9')) {
continue;
} else return 0;
return 1;
}
Or better
#include <ctype.h>
...
int checkString(char str1[]) {
int i, x=0, p;
p=strlen(str1);
for (i = 0; i < p ; i++)
if (isalnum(str1[i]) || (str1[i] == ' '))
continue;
else return 0;
return 1;
}
This is happening because you are taking input with scanf(%s,&str). In this way of input only characters before space \n or other whitespace characters are stored. So your when you enter space the input is stored only upto space.
eg, you input helloo 1234
Your str stores only helloo and 1234 remains in buffer. Try using getchar().
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
#define N 100
int checkString(char str1[]);
void main()
{
char str1[N];
int i=0;
while(1)
{
str1[i++]=getchar();
if(str1[i-1]=='\n') break;
}
printf("%d",checkString(str1));
getch();
}
int checkString(char str1[])
{
int i, x=0, p;
p=strlen(str1);
for (i = 0; i < p ; i++)
{
if ((str1[i] >= 'a' && str1[i] <= 'z') || (str1[i] >= 'A' && str1[i] <= 'Z') || (str1[i] == ' '))
{
continue;
}
else{ return 0; }
}
return 1;
}
When you use scanf("%s",str1);,you input hello 112,what str1 gets is hello.So you can use fgets(str1,N,stdin); to get the string.I think it will work.
There is a problem with your input String
scanf() which will take your input up to space only as it is whitespace
So when you input as hello 1234 actual input it is checking is hello . Check this by printing what you are taking input (that is print str1). Then you will come to know mistake in this code.
You can use gets or fgets to solve the problem.
if you print back the string you just scanf()ed you will notice that it only gets the first portion of all inputs. i.e. anything after the white space including the white space is ignored.
you could use getch() (windows) or getchar() (linux) to get every char input and terminate when you have a "\n" (newline)
source: http://www.cplusplus.com/reference/cstdio/scanf/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define N 100
int checkString(char str1[]);
void main()
{
int i = 0;
int c;
char str1[N];
memset(str1, 0, sizeof(str1));
do {
c = getchar();
str1[i++] = c;
} while ((c != '\n') && (i < (N - 1))); // (i < N - 1) reserves one place for null char
// last char is '\n' - remove it.
str1[i-1] = 0;
printf("Result: %s\n", checkString(str1) ? "letters and/or spaces only" : "other characters other than spaces and/or letters present");
}
// expects a null terminated string
int checkString(char str1[])
{
char* p = str1;
while (*p) {
if (!isalpha(*p) && !isspace(*p)) {
return 0;
}
p++;
}
return 1;
}

checking if the characters in a string are either alphabets, numbers, or special characters. in c

i have been working on a question which asks to check the numbers, alphabets or other special characters in a string.
for example if you are given two inputs. one is an integer which is string length and the second input is the string of characters.
input1: 6
input2: 4!hs%5.
the output should be: noaaon.
n stands for number, a stands for alphabets, and o stands for other.
#include<stdio.h>
#include<string.h>
int main(){
char c[20];
int n,i;
scanf("%d %s",&n,c);
for(i=1;c[i]<=n;i++)
if(i>='a' && i<='z')
printf("%c\n",(c[i]));
if(i=='!')
printf("%c \n",i);
else
{
printf("%c \n",);
}
return 0;
}
Why not just try something much simpler like isalpha() and isdigit() like
for( i = 0 ; i < n ; i++ )
{
if ( isalpha( c[i] ) )
// it is an alphabet, so some code
else if ( isdigit ( c[i] ) )
// it is a number , so some code
else
// it is some other character
}
This is actually much simpler than your current code
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
char input[10];
char out[10];
int i;
memset(out, '\0', 10);
scanf("%s", input);
for(i = 0; i < strlen(input); ++i){
if( (c[i] >= 'a' && c[i] <= 'z') || (c[i] >= 'A' && c[i] <= 'Z') ){
out[i] = 'a';
}
else if(isdigit(c[i])){
out[i] = 'n';
}
else{
out[i] = 'o';
}
}
printf("%s", out);
return 0;
}
You can try it here: http://ideone.com/d8Id1Z

checking if character is upper or lower case in alphanumeric

I have this C code. If I input a LOL123 it should display that it is uppercase. And lol123 it is in lowercase. How do I use isalpha in excluding non-numerical input when checking isupper or is lower?
#include <stdio.h>
#define SIZE 6
char input[50];
int my_isupper(char string[]);
int main(){
char input[] = "LOL123";
int m;
m= isupper(input);
if( m==1){
printf("%s is all uppercase.\n", input);
}else
printf("%s is not all uppercase.\n", input);
return 0;
}
int my_isupper(char string[]){
int a,d;
for (a=0; a<SIZE); a++){
d= isupper(string[a]) ;
}
if(d != 0)
d=1;
return d;
}
For upper-case function just loop trough the string and if a lowercase character is encountred you return false like value. And don't use standard library functions names to name your own functions. Use isUpperCase instead.
Live Demo: https://eval.in/93429
#include <stdio.h>
#include <string.h>
int isUpperCase(const char *inputString);
int main(void)
{
char inputString1[] = "LOL123";
char inputString2[] = "lol123";
printf("%s is %s\n", inputString1, isUpperCase(inputString1)?"upper-case":"not upper-case");
printf("%s is %s\n", inputString2, isUpperCase(inputString2)?"lower-case":"not upper-case");
return 0;
}
int isUpperCase(const char *inputString)
{
int i;
int len = strlen(inputString);
for (i = 0; i < len; i++) {
if (inputString[i] >= 'a' && inputString[i] <= 'z') {
return 0;
}
}
return 1;
}
int my_isalpha_lower(int c) {
return ((c >= 'a' && c <= 'z')); }
int my_isalpha_upper(int c) {
return ((c >= 'A' && c <= 'Z')); }
int isdigit(int c) {
return (c >= '0' && c <= '9'); }
while (*s) {
if (!is_digit(*s) && !my_isalpha_lower(*s))
{
//isnot lower but is alpha
}
else if (!is_digit(*s) && !my_alpha_upper(*s))
{
//is not upper but is alpha
}
s++;
}
char c = ...;
if (isalpha(c))
{
// do stuff if it's alpha
} else {
// do stuff when not alpha
}
You have a lot to learn, besides using a name of a standard function your design also is completely flawed. You only memorize the case of the last character that you encounter in your for loop, so the result that you return is not at all what you think.
Some more observations:
Don't use the name of a standard function for your own.
Arrays decay to pointers when then are used as function parameters. You have no way to automatically detect the size of the array.
You expect your return from isupper to be a logical value. Testing that again with ==1 makes not much sense.
You have two different variables called input, one in file scope, one in main.
Fairly simple:
#include <ctype.h>
/**
* Will return true if there's at least one alpha character in
* the input string *and* all alpha characters are uppercase.
*/
int allUpper( const char *str )
{
int foundAlpha = 0;
int upper = 1;
for ( const char *p = str; *p; p++ )
{
int alpha = isalpha( *p );
foundAlpha = foundAlpha || alpha;
if ( alpha )
upper = upper && isupper( *p );
}
return foundAlpha && upper;
}

Resources