Checking if string is only letters and spaces - arrays

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;
}

Related

How to have a function output a string, not just the first word

I'm writing a function to capitalize every lowercase character in a string. It takes a string from the user and that is the input to the function. My program works if the user doesn't enter spaces, but when there is a space in the string, the function ends.
#include <stdio.h>
char *uppercase(char *c) {
int i = 0;
while (c[i] != '\0') {
if (123 > c[i] && c[i] > 96)
c[i] = c[i] - 'a' + 'A';
i++;
}
return c;
}
int main() {
char input[100];
printf("Enter the phrase: ");
scanf("%s", input);
printf("%s", uppercase(input));
return 0;
}
Examples:
Input: test test
Output: TEST
Input: Hello
Output: HELLO
Input: How are you
Output: HOW
I think it has to do with the while statement? Thanks for the help.
The problem is not in the while statement, but rather due to the scanf() format: %s reads a single word from the input, leaving the rest of the line in the stdin buffer. Note also that typing a word with more than 99 characters will cause undefined behavior because scanf() will write beyond the end of the input array. Using %99s would prevent this problem, but not solve your issue.
You should use fgets() to read a full line of input from stdin.
Furthermore, instead of using hard coded ASCII values, you should use character constants such as 'a' and 'z' or the functions from <ctype.h>.
Here is a modified version using ASCII:
#include <stdio.h>
char *uppercase(char *s) {
int i = 0;
while (s[i] != '\0') {
if (s[i] >= 'a' && s[i] <= 'z')
s[i] = s[i] - 'a' + 'A';
i++;
}
return s;
}
int main() {
char input[100];
printf("Enter the phrase: ");
if (fgets(input, sizeof input, stdin)) {
fputs(uppercase(input), stdout);
}
return 0;
}
Here is a more portable one using <ctype.h>:
#include <ctype.h>
#include <stdio.h>
char *uppercase(char *s) {
int i = 0;
unsigned char c;
while ((c = s[i]) != '\0') {
if (islower(c))
s[i] = toupper(c);
i++;
}
return s;
}
This can be further simplified as toupper() can be called for all byte values from 0 to UCHAR_MAX:
#include <ctype.h>
#include <stdio.h>
char *uppercase(char *s) {
for (size_t i = 0; s[i] != '\0'; i++) {
s[i] = toupper((unsigned char)c);
}
return s;
}
Either use
scanf ("%99[^\n]", input);
or
fgets( input, sizeof( input ), stdin );
Also it is a bad practice to use magic numbers like 123 or 96
if (123 > c[i] && c[i] > 96)
The code will be more readable if you will write at least
if ( 'a' <= c[i] && c[i] <= 'z' )
Also instead of the while loop it is better to use the for loop like
for ( char *p = c; *p; ++p )
{
if ( 'a' <= *p && *p <= 'z' )
{
*p = *p - 'a' + 'A';
}
}

How to print strings that have more consonants than vowels?

Enter the array of 20 strings. Make program that prints out strings which have more consonants than vowels and in which letter 'r' is repeated at least 3 times.
I belive that the problem is in my if loops, but somehow i fail to understand why it does not work properly. It prints every string I enter.
This is the code i wrote:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char string[20][50];
int i, j;
int vowels=0;
int consonants=0;
int repeated_r=0;
printf("Enter the array of 20 strings:\n");
for(i=0;i<20;i++){
gets(string[i]);
}
for(i=0;i<20;i++){
for(j=0;j<50;j++){
if(string[i][j] == 'r'){
repeated_r++;
}
else if(string[i][j] == 'a' || string[i][j] == 'e' || string[i][j] == 'i' || string[i][j] == 'o' || string[i][j] == 'u'){
vowels++;
}
else{
consonants++;
}
}
if(consonants>vowels && repeated_r>=3){
fflush(stdin);
puts(string[i]);
}
}
return 0;
}
You need to reset the counters after processing each string.
And don't use gets use fgets instead.
for(i=0;i<20;i++){
for(j=0;j<50;j++){
if(string[i][j] == 'r'){
repeated_r++;
}
else if(string[i][j] == 'a' || string[i][j] == 'e' || string[i][j] == 'i' || string[i][j] == 'o' || string[i][j] == 'u'){
vowels++;
}
else{
consonants++;
}
}
if(consonants>vowels && repeated_r>3){
fflush(stdin);
puts(string[i]);
}
//Reset the counters
consonants =0;
vowels =0;
repeated_r =0;
}
}
Also note that in your current code r is not considered as consonant.
You are not resetting the initial values of the variables in the outer loop
int vowels=0;
int consonants=0;
int repeated_r=0;
Also the condition in the inner loop
for(j=0;j<50;j++){
^^^^
is not correct because in this case there is an access to memory beyond stored strings in the array.
The letter 'r' is not counted as a consonant.
Take into account that the function gets is not a standard C function that is it is not supported by the C Standard any more.
And this call
fflush(stdin);
has undefined behavior.
I can suggest the following solution as shown in the demonstrative program below.
#include <stdio.h>
#include <string.h>
int main( void )
{
enum { M = 3, N = 50 };
char s[M][N];
for ( size_t i = 0; i < M; i++ )
{
fgets( s[i], N, stdin );
s[i][strcspn( s[i], "\n" )] = '\0';
}
const char *vowels = "aeiou";
const char r = 'r';
for ( size_t i = 0; i < M; i++ )
{
size_t repeated_r = 0;
size_t vowels_count = 0;
size_t n = strlen( s[i] );
for ( size_t j = 0; j < n; j++ )
{
repeated_r += s[i][j] == r;
vowels_count += strchr( vowels, s[i][j] ) != NULL;
}
if ( repeated_r >= 3 && vowels_count < n - vowels_count )
{
puts( s[i] );
}
}
return 0;
}
If to enter the following strings
Hello World
errors
photosynthesis_bro
then the program output might look like
errors
there is one more problem in your code, ypu're using gets. It'll also include white spaces so say if your string is "_ _ rrrbaeeeeiou _ ". It will print this string but actually this string should not have been printed.
Note that "" means a blank space.
According to your code, "_" will be counted in consonants and even though there are 4 consonants in your string(3 r and 1 b) and 8 vowels, it will print this string as output since the blank spaces will be counted as consonants.
Also in your code r is not counted as consonant

Strange output of the C program using toupper function

Here is my program to uppercases all letter inputted from the standard input. But some output is very strange. For example, if input is "lorem ipsum" and output will be "LOREM IPSUMS?". If input is a single character such as 'm', the output will be "MZ#X?" . "S?" and "Z#X?" should not be here but they append to the output.
Why this happens?
#include <stdio.h>
#include <ctype.h>
int main(void){
char input;
char upper[100];
int count = 0;
while((input = getchar())){
if(input == '\n')
break;
if(input >= 'a' && input <= 'z')
input = toupper(input);
*(upper + count) = input;
count++;
}
printf("%s\n", upper);
return 0;
}
Your code is working for me.
The only thing, but this is expected, you get garbage after the string, because your char array has a length of 100. You should put a 0 at the end of the string to tell printf your string ends there. put
*(upper + count) = 0;
right before printf.
Your code has a some issues:
the NULL terminator isn't added at the end of the string.
There isn't any check of index out of bounds of the allocated array.
User may interrupt input without a newline making the program loop forever.
getchar returns an int.
You can try this fix:
#include <stdio.h>
#include <ctype.h>
const int MAX_CHAR = 101;
int main() {
int input;
char upper[MAX_CHAR];
int count = 0;
while( count < MAX_CHAR - 1 ) {
input = getchar();
if ( input == EOF || input == '\n' || input == '\r' )
break;
if ( input >= 'a' && input <= 'z' )
input = toupper(input);
upper[count] = input;
count++;
}
// add the null terminator
upper[count] = '\0';
printf("%s\n", upper);
return 0;
}
You might want to set all the elements in your array to be 0 (ASCII NUL) because we have no idea what is in the upper array.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void){
char input;
char upper[100];
int count = 0;
memset(upper, 0, 100);
while((input = getchar())){
if(input == '\n')
break;
if(input >= 'a' && input <= 'z')
input = toupper(input);
*(upper + count) = input;
count++;
}
printf("%s\n", upper);
return 0;
}
If you are not sure what memset does, you can do it with a for loop.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void){
char input;
char upper[100];
int count = 0;
for (int i = 0; i < 100; i++) {
upper[i] = 0;
}
while((input = getchar())){
if(input == '\n')
break;
if(input >= 'a' && input <= 'z')
input = toupper(input);
*(upper + count) = input;
count++;
}
printf("%s\n", upper);
return 0;
}

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

Removing spaces and special characters from string

How do you remove spaces and special characters from a string?
I couldn't find a single answer while googling. There were a lot related to other languages, but not C. Most of them mentioned the use of regex, which isn't C standard (?).
Removing a simple space is easy:
char str[50] = "Remove The Spaces!!";
Then a simple loop with a if-statement:
if (str[i] != ' ');
Output would be:
RemoveTheSpaces!!
What do I add to the if-statement so it would recognize special characters and remove them?
My definition of special characters:
Characters not included in this list:
A-Z a-z 0-9
This is probably not the most efficient way of achieving this but it will get the job done fairly fast.
Note: this code does require you to include <string.h> and <ctype.h>
char str[50] = "Remove The Spaces!!";
char strStripped[50];
int i = 0, c = 0; /*I'm assuming you're not using C99+*/
for(; i < strlen(str); i++)
{
if (isalnum(str[i]))
{
strStripped[c] = str[i];
c++;
}
}
strStripped[c] = '\0';
There are millions of different ways this can be done. Here is just one example that is not using any additional storage and performs the removal of unneeded characters "in-place":
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
static void my_strip(char *data)
{
unsigned long i = 0; /* Scanning index */
unsigned long x = 0; /* Write back index */
char c;
/*
* Store every next character in `c` and make sure it is not '\0'
* because '\0' indicates the end of string, and we don't want
* to read past the end not to trigger undefined behavior.
* Then increment "scanning" index so that next time we read the
* next character.
*/
while ((c = data[i++]) != '\0') {
/* Check if character is either alphabetic or numeric. */
if (isalnum(c)) {
/*
* OK, this is what we need. Write it back.
* Note that `x` will always be either the same as `i`
* or less. After writing, increment `x` so that next
* time we do not overwrite the previous result.
*/
data[x++] = c;
}
/* else — this is something we don't need — so we don't increment the
`x` while `i` is incremented. */
}
/* After all is done, ensure we terminate the string with '\0'. */
data[x] = '\0';
}
int main()
{
/* This is array we will be operating on. */
char data[512];
/* Ask your customer for a string. */
printf("Please enter a string: ");
if (fgets(data, sizeof(data), stdin) == NULL) {
/* Something unexpected happened. */
return EXIT_FAILURE;
}
/* Show the customer what we read (just in case :-)) */
printf("You have entered: %s", data);
/*
* Call the magic function that removes everything and leaves
* only alphabetic and numberic characters.
*/
my_strip(data);
/*
* Print the end result. Note that newline (\n) is there
* when we read the string
*/
printf("Stripped string: %s\n", data);
/* Our job is done! */
return EXIT_SUCCESS;
}
I put a lot of comments in there so hopefully the code doesn't need explanation. Hope it helps. Good Luck!
This is just a silly suggestion.
char ordinary[CHAR_MAX] = {
['A']=1,['B']=1,['C']=1,['D']=1,['E']=1,['F']=1,['G']=1,['H']=1,['I']=1,
['J']=1,['K']=1,['L']=1,['M']=1,['N']=1,['O']=1,['P']=1,['Q']=1,['R']=1,
['S']=1,['T']=1,['U']=1,['V']=1,['W']=1,['X']=1,['Y']=1,['Z']=1,
['a']=1,['b']=1,['c']=1,['d']=1,['e']=1,['f']=1,['g']=1,['h']=1,['i']=1,
['j']=1,['k']=1,['l']=1,['m']=1,['n']=1,['o']=1,['p']=1,['q']=1,['r']=1,
['s']=1,['t']=1,['u']=1,['v']=1,['w']=1,['x']=1,['y']=1,['z']=1,
['0']=1,['1']=1,['2']=1,['3']=1,['4']=1,['5']=1,['6']=1,['7']=1,['8']=1,
['9']=1,
};
int is_special (int c) {
if (c < 0) return 1;
if (c >= CHAR_MAX) return 1;
return !ordinary[c];
}
void remove_spaces_and_specials_in_place (char *str) {
if (str) {
char *p = str;
for (; *str; ++str) {
if (!is_special(*str)) *p++ = *str;
}
*p = '\0';
}
}
Using your if statement:
if (str[i] != ' ');
With a little logic (the characters have to be in the range a-z or A-Z or 0-9:
If ( !('a' <= str[i] && 'z' >= str[i]) &&
!('A' <= str[i] && 'Z' >= str[i]) &&
!('0' <= str[i] && '9' >= str[i])) then ignore character.
This is Ascii Code Range
Char:Dec
0:48, 9:57
A:65, Z:90
a:97, z:122
try this:
char str[50] = "Remove The Spaces!!";
int i =0;
for(; i<strlen(str); i++)
{
if(str[i]>=48 && str[i]<=57 || str[i]>=65 && str[i]<=90 || str[i]>=97 && str[i]<=122)
//This is equivalent to
//if(str[i]>='0' && str[i]<='9' || str[i]>='A' && str[i]<='Z' || str[i]>='a' && str[i]<='z')
printf("alphaNumeric:%c\n", str[i]);
else
{
printf("special:%c\n", str[i]);
//remove that
}
}
#include <stdio.h>
#include <string.h>
main()
{
int i=0, j=0;
char c;
char buff[255] = "Remove The Spaces!!";
for(; c=buff[i]=buff[j]; j++){
if(c>='A' && c<='Z' || c>='a' && c<='z' || c>='0' && c<='9'){
i++;
}
}
printf("char buff[255] = \"%s\"\n", buff);
}
include < stdio.h >
int main()
{
char a[100];
int i;
printf("Enter the character : ");
gets(a);
for (i = 0; a[i] != '\0'; i++) {
if ((a[i] >= 'a' && a[i] <= 'z') || (a[i] >= 'A' && a[i] <= 'Z')
|| (a[i] - 48 >= 0 && a[i] - 48 <= 9)) {
printf("%c", a[i]);
} else {
continue;
}
}
return 0;
}

Resources