If loop in C not iterating properly - c

Writing a word counter on C. I'm counting the number of spaces in the string to determine the number of words. I'm guessing there's something wrong with my if statement. Sometimes it counts the number of words and other times it's throwing up random numbers? For instance "my red dog" has three words but "I drink rum" has one word and "this code makes no sense" has three. It's printing the length of the strings fine for each.
Here's the part of the code in question:
void WordCounter(char string[])
{ int counter = 1;
int i = 0;
int length = strlen(string);
printf("\nThe length of your string is %d", length);
for( i=0;i<length;i++){
if (string[i] == ' ')
{
counter+=1;
++i;
}
else
{
counter +=0;
++i;
}
}
printf("There are %d words in this sentence and i is equal to: %d", counter, i);
}

The i++ part of the for loop means that i is incremented at every loop, you should not do it again inside the loop. Also, your else is not necessary here. You'll want to remove bits to have:
for( i=0;i<length;i++) {
if (string[i] == ' ')
{
counter+=1;
}
}

The biggest problem with your posted code is that it incorrectly increments i where it should not.
for( i=0;i<length;i++){
if (string[i] == ' ')
{
counter+=1;
++i; // here
}
else
{
counter +=0;
++i; // here
}
}
Neither of the //here lines above are needed for what you appear to be trying to do. Furthermore, the entire else-block is pointless, as it modifies nothing except i, which it shouldn't be doing. Therefore, a more correct approach would be simply:
for(i=0; i<length; ++i)
{
if (string[i] == ' ')
++counter;
}
This increments counter whenever you index a space ' ' character. For a trivial algorithm, this will probably suffice to what you were trying.
Counting Spaces, Not Words
Your algorithm really doesn't count words, it simply counts the number of space characters encountered, plus one. This mean some inputs, such as those below (quotes used to note content in the string, not actually present), will not return an accurate word-count:
// shoud be zero, but returns one
""
// should be zero, but returns four (three spaces)
" "
// should be one, but returns five (two spaces, either side)
" word "
// should be two, but returns three (two spaces between)
"word word"
etc.
A more robust algorithm is required. Note this does NOT solve everything, but it makes great leaps in getting you closers to counting what we call "words". That is, non-whitespace characters separated by whitespace characters and potentially buttressing up to the end of the string.
This uses pointers rather than indexes. In my opinion it is simply easier to read, and declutters the code from indexing syntax, thereby amplifying what is really going on: consuming whitespace, then consuming non-whitespace that we call a "word". Comments inline should explain what is going on:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int WordCounter(const char *s)
{
int counter = 0;
// while we haven't reached terminating nullchar
while (*s)
{
// discard all whitespace until nullchar or non-whitespace found
for (; *s && isspace((unsigned char)*s); ++s);
// if not nullchar, we have the start of a "word"
if (*s)
{
++counter;
// discard all text until next whitespace or nullchar
for (; *s && !isspace((unsigned char)*s); ++s);
}
}
return counter;
}
int main()
{
const char *s1 = "There should be eight words in this string";
printf("\"%s\"\nwords: %d\n", s1, WordCounter(s1));
const char *s2 = " There should\t\t\tbe eight\n in\n this\n string too\n ";
printf("\"%s\"\nwords: %d\n", s2, WordCounter(s2));
const char *s3 = "One";
printf("\"%s\"\nwords: %d\n", s3, WordCounter(s3));
const char *s4 = "";
printf("\"%s\"\nwords: %d\n", s4, WordCounter(s4));
return 0;
}
Output
"There should be eight words in this string"
words: 8
" There should be eight
in
this
string too
"
words: 8
"One"
words: 1
""
words: 0
Not Perfect; Just Better
The prior algorithm still isn't perfect. To accurately extract single words would require knowledge of punctuation, potentially hyphenation, etc. But it is much, much closer to what appears to be the goal. Hopefully you get something out of it.

Your code has increment i in 3 different places. The increment needs only the loop.
Try this code:
for( i=0;i<length;i++){
if (string[i] == ' ')
{
counter++;
}
}

You´re incrementing i 2 times in the same loop. One in the for statement and one in the loop. It means you´re checking only one character on two. It can explain why all pair spaces are not in the count:
I put in Bolt all pair characters:
"my red dog": Both spaces are unpair numbers
"I drink rum": Both spaces are unpair numbers
Here is your corrected source code:
void WordCounter(char string[]){
int counter = 1;
int i = 0;
int length = strlen(string);
printf("\nThe length of your string is %d", length);
for( i=0;i<length;i++){
if (string[i] == ' ')
{
counter+=1;
}
}
printf("There are %d words in this sentence and i is equal to: %d", counter, i);
}

You even do not need the i variable
counter = 0;
while(*str)
counter += *str++ == ' ' ? 1 : 0;
printf("There are %d spaces (not words as you may have more spaces between words) in this sentence and length of the string is: %d", counter, length);
int isDelimeter(int ch, const char *delimiters)
{
return strchr(delimiters, ch) != NULL;
}
const char *skipDelimiters(const char *str, char *delimiters)
{
while (*str && isDelimeter(*str, delimiters)) str++;
return str;
}
const char *skipWord(const char *str, char *delimiters)
{
while (*str && !isDelimeter(*str, delimiters)) str++;
return str;
}
const char *getWord(const char *str, char *buff, char *delimiters)
{
while (*str && !isDelimeter(*str, delimiters)) *buff++ = *str++;
*buff = 0;
return str;
}
int countWords(const char *str, char *delimiters)
{
int count = 0;
while (*str)
{
str = skipDelimiters(str, delimiters);
if (*str) count++;
str = skipWord(str, delimiters);
}
return count;
}
int printWords(const char *str, char *delimiters)
{
char word[MAXWORDLENGTH];
int count = 0;
while (*str)
{
str = skipDelimiters(str, delimiters);
if (*str)
{
count++;
str = getWord(str, word, delimiters);
printf("%d%s word is %s\n", count, count == 1 ? "st" : count == 2 ? "nd" : count == 3 ? "rd" : "th", word);
}
}
return count;
}

Related

camelCase function in C, unable to remove duplicate chars after converting to uppercase

void camelCase(char* word)
{
/*Convert to camelCase*/
int sLength = stringLength(word);
int i,j;
for (int i = 0; i < sLength; i++){
if (word[i] == 32)
word[i] = '_';
}
//remove staring char '_',*,numbers,$ from starting
for (i = 0; i < sLength; i++){
if (word[i] == '_'){
word[i] = toUpperCase(word[i + 1]);
}
else
word[i] = toLowerCase(word[i]);
}
word[0] = toLowerCase(word[0]);
//remove any special chars if any in the string
for(i = 0; word[i] != '\0'; ++i)
{
while (!((word[i] >= 'a' && word[i] <= 'z') || (word[i] >= 'A' && word[i] <= 'Z') || word[i] == '\0') )
{
for(j = i; word[j] != '\0'; ++j)
{
word[j] = word[j+1];
}
word[j] = '\0';
}
}
}
int main()
{
char *wordArray;
wordArray = (char*)malloc(sizeof(char)*100);
// Read the string from the keyboard
printf("Enter word: ");
scanf("%s", wordArray);
// Call camelCase
camelCase(wordArray);
// Print the new string
printf("%s\n", wordArray);
return 0;
}
I am writing a function that takes in this for example _random__word_provided, and I am to remove any additional underscores or special characters, capitalize the first word after an underscore and reprint the word without any underscores. The above example would come out like this randomWordProvided.
When I run my code though this is what I am getting rrandomWwordPprovided. I am unsure where my loop is having issues. Any guidance would be appreciated. Thank you!
You are WAY over-processing the string...
First measure the length. Why? You can find the '\0' eventually.
Then convert ' 's to underscores (don't use magic numbers in code).
Then force almost everything to lowercase.
Then try to "strip out" non-alphas, cajoling the next character to uppercase.
(The non-alpha '_' has already been replaced with an uppercase version of the next character... This is causing the "thewWho" duplication to remain in the string. There's no indication of '$' being addressed as per your comments.)
It seems the code is traversing the string 4 times, and the state of the string is in flux, leading to hard-to-understand intermediate states.
Process from beginning to end in one pass, doing the right thing all the way along.
char *camelCase( char word[] ) { // return something usable by the caller
int s = 0, d = 0; // 's'ource index, 'd'estination index
// one sweep along the entire length
while( ( word[d] = word[s] ) != '\0' ) {
if( isalpha( word[d] ) ) { // make ordinary letters lowercase
word[ d ] = tolower( word[ d ] );
d++, s++;
continue;
}
// special handling for non-alpha. may be more than one!
while( word[s] && !isalpha( word[s] ) ) s++;
// end of non-alpha? copy alpha as UPPERCASE
if( word[s] )
word[d++] = toupper( word[s++] );
}
// make first character lowercase
word[ 0 ] = tolower( word[ 0 ] );
return word; // return modified string
}
int main() {
// multiple test cases. Add "user input" after algorithm developed and tested.
char *wordArray[] = {
"_random__word_provided",
" the quick brown fox ",
"stuff happens all the time",
};
for( int i = 0; i < 3; i++ )
puts( camelCase( wordArray[i] ) );
return 0;
}
randomWordProvided
theQuickBrownFox
stuffHappensAllTheTime
There may come comments pointing out that the ctype.h functions receive and return unsigned datatypes. This is a "casting" elaboration that you can/should add to the code if you ever expect to encounter something other than 7-bit ASCII characters.
In my opinion, there's a very simple algorithm that just requires you to remember the last character parsed only:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void camelCase(char* source)
{
/*Convert to camelCase*/
char last = '_',
*dest = source;
/* while we are not at the string end copy the char values */
while ((*dest = *source++) != '\0') {
/* if the char is a lower case letter and the previous was a '_' char. */
if (islower(*dest) && last == '_')
*dest = toupper(*dest);
/* update the last character */
last = *dest;
/* to skip on the underscores */
if (*dest != '_') dest++;
}
} /* camelCase */
int main()
{
char wordArray[100]; /* better use a simple array */
// Read the string from the keyboard
printf("Enter identifiers separated by spaces/newlines: ");
/* for each line of input */
while (fgets(wordArray, sizeof wordArray, stdin)) {
for ( char *word = strtok(wordArray, " \t\n");
word;
word = strtok(NULL, " \t\n"))
{
printf("%s -> ", word);
// Call camelCase
camelCase(word);
// Print the new string
printf("%s\n", word);
}
}
return 0;
}
if you actually want to skip the first character (and don't convert it to uppercase), you can initialize last with a different char (e.g. '\0')

Beginner C: Reading Age

I'm studying elementary programming in C and I'm doing a challenge to determine the reading age of various sentences. This is achieved by determining the amount of sentences in a string etc. I have some code that does the my first very basic step but it's not quite working as expected.
I'm thinking this is because my knowledge of the strlen function etc isn't sufficient.
I don't want to cheat for the answer as I like the sense of achievement from the problem solving. But would it be possible to get a gentle push in the right direction if at all possible?
char sentence[] = "One fish. Two fish. Red fish. Blue fish.";
int main(void)
{
int sentence_count = 0;
int word_count = 0;
int i;
int length = strlen(sentence);
for (i = 0; i == strlen(sentence); i++) //need to somehow go through a string one char at a time until the end.
{
if (sentence[i] == '.' || sentence[i] == '!' || sentence[i] == ';' || sentence[i] == '?')
{
return sentence_count ++;
}
if (sentence[i] == '\0')
{
return word_count ++;
}
}
printf("There are %i in %i sentences.\n", word_count, sentence_count);
printf("%i\n", length);
}
First Problem -
for (i = 0; i == strlen(sentence); i++)
This state should be -
for (i = 0; i < strlen(sentence); i++)
In your case, it would be terminating on the first iteration itself. However, You need to loop until you have reached the index - strlen(sentence).
Do recall that for loop has syntax - for(initialisation; condition; increment/decrement) will run only until the condition evaluates to true. So, you need the condition to evaluate to true till you have traversed the whole string which is done by the second line of code mentioned above.
A better alternative approach would be -
for (i = 0; sentence[i] != '\0'; i++)
which means the loop will run until you encounter a null-terminated character.
Second Problem -
return sentence_count ++;
.
.
return word_count ++;
Here, you don't need to add the return keyword before the above two statements. The return will directly exit from your program. Simply writing sentence_count++ and word_count++ would be correct.
Third Problem -
sentence[i] == '\0'
This statement doesn't quite fit with the logic that we are trying to achieve. The statement instead must check if the character is a space and then increment the word count -
if (sentence[i] == ' ')
{
return word_count ++;
}
Your for loop condition is the main problem; for (i = 0; i == strlen(sentence); i++) reads as "on entry, set i to 0, enter the body each time i is equal to the length of sentence, increment i at the end of each loop". But this means the loop never runs unless sentence is the empty string (has strlen of 0). You want to test i < strlen(sentence) (or to avoid potentially recomputing the length over and over, use the length you already calculated, i < length).
You also need to remove your returns; the function is supposed to count, and as written, it will return 0 the instant it finds any of the target characters, without using the incremented values in any way. Put a return 0; at the end of main to indicate exiting successfully (optionally, stdlib.h can be included so you can return EXIT_SUCCESS; to avoid magic numbers, but it's the same behavior).
The information in others answers being already covered, here are a couple of other suggestions for your consideration.
Remove function calls, such as strlen() from within the for(;;) loop. You've already obtained the length with:
int length = strlen(sentence);
Now, just use it in your for loop:
for(i = 0; i < length ; i++)//includes replacement of == with <
Encapsulate the working part of your code, in this case the the counting of words and sentences. The following uses a different approach, but its the same idea:
//includes deliminators for common end-of-sentence punctuation:
int count_sentences(const char *buf)
{
const char *delim = {".?!"};//add additional 'end-of-sentence' punctuation as needed.
char *tok = NULL;
int count = 0;
char *dup = strdup(buf);//preserve original input buffer
if(dup)
{
tok = strtok(dup, delim);
while(tok)
{
count++;
tok = strtok(NULL, delim);
}
free(dup);
}
return count;
}
One additional idea, that is out of scope with your original code, but very useful in practice is to remove any parts of the buffer that may not be part of the sentence, i.e. leading or trailing space. In your example, you have the test case for your sentences tightly defined within a string literal:
char sentence[] = "One fish. Two fish. Red fish. Blue fish.";
This is not incorrect, but what would happen at some point your code were to be expected to work with string buffers not so neatly packaged? i.e. leading or trailing white space characters in the buffer to be processed?
"\n\n\tOne fish. Two fish. Red fish. Blue fish.\f"
Removing unknown and unwanted content from the buffer prior to processioning simplifies the code doing the work, in this case counting sentences. Following is a simple example of how this can be done.
//prototype:
char *new = clear_leading_trailing_whitespace(sentence);
char * clear_end_space(const char *buf)
{
char *new = buf;
//clear leading whitespace
while (isspace(*new))
{
new++;
}
//clar trailing whitespace
int len = strlen(new);
while(isspace(*(new + len-1)))
{
len--;
}
*(new + len) = 0;
return buf;
}
Next, the following code segment is intending to count words:
if (sentence[i] == '\0')
{
return word_count ++;
}
But after being initialized to 0, word_count is only incremented once when seeing the null terminator, \0 once. Word count is generally a count of spaces between non-sentence terminating and non-whitespaces characters in a buffer. Or in otherwords, tracking how many clusters of non-whitespace there are. The following is a way to do this:
void countwords(const char *text, *count)
{
bool reading_word = false; // Flag
int words = 0;
for(int i=0; i<strlen(text); i++)
{
if(isspace(text[i])) {
reading_word = false;
}
else if(isalpha(text[i])) {
if(!reading_word) {
reading_word = true;
words++;
}
}
}
*count = words;
}
Functions like this can be used to greatly simplify contents of the main function:
char sentence[] = "One fish. Two fish. Red fish. Blue fish.";
int main(void)
{
int sentence_count = 0;
int word_count = 0;
char *new = clear_leading_trailing_whitespace(sentence);
countwords(new, &word_count);
sentence_count = count_sentences(new);
...
printf("There are %d words in %d sentences.\n", word_count, sentence_count);
}

C - Reverse order of words in an array of Strings

I did this program to reverse the order of the words in the give string. (And it works)
i.e. Output: sentence first the is This
However I am stuck when it comes to adding another sentence to the array.
For example I need to have an array {"This is the first sentence", "And this is the second"} producing as output: sentence first the is This , second the is this And
int main() {
char str[] = {"This is the first sentence"};
int length = strlen(str);
// Traverse string from end
int i;
for (i = length - 1; i >= 0; i--) {
if (str[i] == ' ') {
// putting the NULL character at the position of space characters for
next iteration.
str[i] = '\0';
// Start from next character
printf("%s ", &(str[i]) + 1);
}
}
// printing the last word
printf("%s", str);
return 0;
}
I am new to C so its not surprising that I got stuck even if the solution is quite easy. Any help would be appreciated! Thanks!
Since you already have the code to print the words of one string in reverse order, I would suggest making that a function which takes a single string as an argument, i.e.:
void print_words_reverse(char * const str) {
// your current code here
}
Then you can call it separately for each string:
char strings[][30] = {
"This is the first sentence",
"And this is the second"
};
for (int i = 0; i < sizeof(strings) / sizeof(*strings); ++i) {
print_words_reverse(strings[i]);
}
Note that since you are modifying the string (by replacing spaces with NUL bytes), the argument needs to be modifiable, which means you are not allowed to call it (in standard C) with a pointer to a string literal, which means you can't simply use const char *strings[] = { "first", "second" }. You could get rid of the ugly constant length (here 30) reserved for every string by making your code not modify the argument string. Or you could have a separate char array for each sentence and then use pointers to those (modifiable) strings.
First, you can try with a two-dimensional array or use an array of pointers.
Secondly, in your approach, you lose the initial value of your string, I don't know how important it is.
This is my fast approach using arrray of pointers.
#include <stdio.h>
#include <string.h>
static void print_word(const char *str)
{
for (int i = 0; str[i] && str[i] != ' '; i++)
printf("%c", str[i]);
putchar(' ');
}
int main(void)
{
int len;
const char *str[] = {"This is the first sentence",
"And this is second", NULL};
for (int i = 0; str[i]; i++) {
for (len = strlen(str[i]); len >= 0; len--) {
if (len == 0)
print_word(&str[i][len]);
else if (str[i][len] == ' ')
print_word(&str[i][len + 1]);
}
putchar('\n');
}
printf("Initial value of array of strings [%s | %s] \n", str[0], str[1]);
return 0;
}
output is:
sentence first the is This
second is this And
Initial value of array of strings [This is the first sentence | And this is second]
I suggest you using memcpy but without altering too much your code this seems to work
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_STRING_LENGTH 100
int main()
{
char *str[] = {"This is the first", "And this is the second sentence"};
const size_t NUM_STRING = sizeof(str)/sizeof(char*);
/*%z used to print size_t variables*/
printf("%zd strings found\n", NUM_STRING);
int length[2];
int i;
for (i=0; i<NUM_STRING; i++)
{
length[i] = strlen(str[i]);
}
printf("length initialized %d %d\n", length[0], length[1]);
// Traverse string from end
int j = 0;
char temp[MAX_STRING_LENGTH];
printf("\n\n");
for (j=0; j<NUM_STRING; j++)
{
/*Make sure the string respect the MAX_STRING_LENGTH limit*/
if (strlen(str[j])>MAX_STRING_LENGTH)
{
printf("ERROR: string %d exceding max string length %d defined in constant "
"MAX_STRING_LENGTH. Exiting from program.\n", j, MAX_STRING_LENGTH);
exit(1);
}
//reset temporary string
memset(temp, '\0', sizeof(temp));
//printf("temp variable reinitialized\n");
for (i = length[j] - 1; i >= 0; i--)
{
temp[i] = str[j][i];
if (str[j][i] == ' ')
{
// putting the NULL character at the position of space characters for next iteration.
temp[i] = '\0';
// Start from next character
printf("%s ", &(temp[i]) + 1);
}
}
// printing the last word
printf("%s ", temp);
}
printf("\n");
return 0;
}

Program to find the longest word in a string

I wrote a program to find the longest word in a string and print the number of letters in the longest word. But the code is not printing. I analyzed the program many times but I could not find the solution.
#include <stdio.h>
#include <string.h>
int main() {
char string[100] = "Hello Kurnool";
int i = 0, letters = 0, longest = 0;
start:
for (; string[i] !=' '; i++) {
letters++;
}
if (letters >= longest)
longest = letters;
if (string[i] == ' ') {
letters = 0;
i++;
goto start;
}
printf("%d", longest);
return 0;
}
Using goto is highly discouraged. You should convert your code to use a loop.
The main problem in your code is you do not stop the scan when you reach the end of the string.
Here is a modified version:
#include <stdio.h>
int main() {
char string[100] = "Hello Kurnool";
int i, letters, longest = 0, longest_pos = 0;
for (i = 0; string[i] != '\0'; i++) {
for (letters = 0; string[i] != '\0' && string[i] != ' '; i++) {
letters++;
}
if (letters > longest) {
longest = letters;
longest_pos = i - longest;
}
}
printf("longest word: %d letters, '%.*s'\n",
longest, longest, string + longest_pos);
return 0;
}
Note that the implementation can be simplified into a single loop:
#include <stdio.h>
int main() {
char string[100] = "Hello Kurnool";
int i, start = 0, longest = 0, longest_pos = 0;
for (i = 0; string[i] != '\0'; i++) {
if (string[i] == ' ') {
start = i + 1;
} else {
if (i - start > longest) {
longest = i - start;
longest_pos = start;
}
}
}
printf("longest word: %d letters, '%.*s'\n",
longest, longest, string + longest_pos);
return 0;
}
Below is my approach. You should use C's string manipulation functions. This is the correct way to deal with strings in C.
In the code below, first I acquire the required bytes to store the input string in heap. Then I use strtok to split the string into tokens based on a delemeter and get the length of each sub string. Finally I free the space that I have allocated with malloc.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define phrase "Hello Kurnool"
int main()
{
char* string = malloc(strlen(phrase)+1);
strcpy(string,phrase);
int longest=0;
char *token;
char delimeter[2] = " ";
/* get the first token */
token = strtok(string, delimeter);
/* walk through other tokens */
while( token != NULL ) {
printf( " %s\n", token );
if(longest < strlen(token)){
longest = strlen(token);
}
token = strtok(NULL, delimeter);
}
printf("%d",longest);
free(string);
return 0;
}
People say - dont use goto but there is nothing inherently wrong with goto. Only thing is if goto is not used judiciously, it makes code more difficult to understand and maintain. For example, the way you have used it in your program ( instead of goto, a loop is perfect fit in such cases). Check this:
To use goto or not?
What is wrong with using goto?
Coming to your code, the for loop condition does not have check for terminating null character
for (; string[i] !=' '; i++) {
Hence it will not stop at the end of string.
To find the number of letters in longest word of string, you can do:
#include <stdio.h>
#include <string.h>
int main() {
char string[100] = "Hello Kurnool";
int i, letters = 0, longest = 0;
for (i = 0; string[i] != '\0'; i++) {
if (string[i] != ' ') {
letters++;
if (letters > longest) {
longest = letters;
}
} else {
letters = 0;
}
}
printf("longest : %d\n", longest);
return 0;
}
First of all,Please avoid using Goto, it is not a good practice.
Secondly, your loop will run infinite times when it iterates the second time because:
for(;string[i]!=' ';i++) // Here String[i] will never be equal to ' ' As there is no white space after your last word.
You can never expect what might be going wrong with your program if you are using
goto statement
which is never advisable to use rather it's bad programming if you use it. Secondly it looks like you are stuck in an infinite loop so her is a solution to your problem:
#include<stdio.h>
#include<string.h>
void main()
{
char s[1000];
scanf("%s",s);
int i=0;
int letters;
int longest=0;
while(s[i]!=NULL)
{
if(s[i]==' ')
{
if(longest>=letters)
{longest=letters;}
letters=0;
}
else
{letters++;}
}
printf("%d\n",longest);
}
So, what I have done is assuming a string s which is the input given by the user. You itterate through s till the last input given by the user after which it encounters a NULL character. Now you are searching for the length of the longest word, so you create a variable letters for counting the no. of letters in each word of the string. And if the string s encounters a space indicating the end of a word, then you check if the variable longest is greater than or less than the word count. And again you initialize letters to 0, so that it can start counting the next word from 0 again.So, by this method at the end i.e. after the while loop terminates we get our required output which is stored in the variable longest.
So, I guess this will print the no. of letters in the longest word.

Find spaces and alphanumeric characters in a string

I need to develop a function that goes through a character string and detects letters (lower and upper cases), digits 0-9 and spaces ' '. If the functions finds only valid characters (the characters listed before) it returns 1 otherwise(if the string has characters like !,&,/,£, etc.) it returns 0. I am aware of a function that finds characters and digits which is isalnum().That is not helpful to find spaces. Does anyone can provide inbuilt or manual function which can detect characters,digits and spaces all together.
I've developed mine as under but function does not detect invalid character !,&,/,£ etc. in middle of the string and therefore it does not return the value I expect.
for (i=0; i<strlen(str); i++) {
if ((str[i]>='A' && str[i]<='Z') || str[i] == ' ' || (str[i]>='a' && str[i]<='z') || (str[i]>='0' && str[i]<='9'))
for (i=0; i<strlen(str); i++) {
char *p = str;
while (*p) {
if (isalnum((unsigned char) *p) || *p == ' ') {
res =1;
} else {
res = 0;
}
p++;
}
}
You can make the code more succinct:
int Validate_Alphanumeric(char *str)
{
unsigned char *ptr = (unsigned char *)str;
unsigned char uc;
while ((uc = *ptr++) != '\0')
{
if (!isalnum(uc) && uc != ' ')
return 0;
}
return 1;
}
Amongst other things, this avoids reevaluating strlen(str) on each iteration of the loop; that nominally makes the algorithm quadratic as strlen() is an O(N) operation and you would do it N times, for O(N2) in total. Either cache the result of strlen(str) in a variable or don't use it at all. Using strlen(str) requires the entire string to be scanned; the code above will stop at the first punctuation or other verboten character without scanning the whole string (but the worst case performance, for valid strings, is O(N)).
I came up with a function that goes through the string and that is able to return 0 if an invalid character (ex. $&$&&(%$(=()/)&)/) is found.
int Validate_Alphanumeric (char str[]) {
int i;
int res;
int valid=0;
int invalid=0;
const char *p = str;
while (*p) {
if (isalnum((unsigned char) *p) || *p == ' ') {
valid++;
} else {
invalid++;
}
p++;
}
if (invalid==0)
res=1;
else
res=0;
return res;
}

Resources