I have a problem, my program in C have to find words with N letters, count them and sort them in lexicographical order and save them to an another file. How could I sort the words in alphabetical order?
this is my code:
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <stddef.h>
#include <string.h>
int main()
{
FILE *r, *fp;
char ch[100],t[100];
int n,i,j,x=0;
r=fopen("text.txt","r");
fp=fopen("text2.txt","w");
fgets(ch, 100, r);
char *start;
int len;
char *s = ch;
char *p = s;
printf("Give the length of word: ");
scanf("%d",&n);
printf("\n\nWords with %d letters: \n\n",n);
while (*p) {
while (*p && isspace(*p))
++p;
start = p;
while (*p && !isspace(*p))
++p;
len = p - start;
if (len == n) {
printf("%.*s\n", len, start);
x++;
fprintf(fp,"%.*s",len, start);
}
}
printf("\nNumber of words: %d ",x);
fclose(fp);
getch();
fclose(r);
}
There's a standard library function for sorting:
https://en.wikipedia.org/wiki/Qsort
It's easy to write a function to sort words alphabeticly it is very similar to sorting alphabetic characters.to sort characters you iterate over the array and compare two characters at a time.if the first is greater than the second,you swap them and loop again until finished.In case of words,you have to iterate over strings,and the iterate over their characters to make the necessary swap.Here is a example :
#include <stdio.h>
int s_bubblesort(int argc,char **argv);
int main(void)
{
char *elements[9] = { "zab","aaaa","bac","zzz","abc","cab","aaa","acc","aaaaaaaaa" };
s_bubblesort(9,elements);
for( int n = 0 ; n < 9 ; n++ )
{
printf("%s\n",elements[n]);
}
}
int s_bubblesort(int argc,char **argv)
{
//loop variables
int i,j;
//p_1 : pointer that points to current string,p_2 : pointer that points to next string
char *p_1 , *p_2 , *tmp;
for( j = 0 ; j < argc ; j++ )
{
for( i = 0 ; i < argc - j - 1 ; i++ )
{
//assign p_1 to current string,and p_2 to next string
p_1 = argv[i] , p_2 = argv[i+1];
//while *p_1 != '\0' and *p_2 != '\0'
while( *p_1 && *p_2 )
{
//if *p_1 less than *p_2,break and move to next iteration
if( *p_1 < *p_2 )
break;
else if( *p_1 > *p_2 || ( ! *(p_2 + 1) && ( *p_1 == *p_2 ) && *(p_1+1) ) ) // if *p_1 > *p_2,or *(p_2 + 1 ) == '\0' and *p_1 == *p_2 and *(p_1 + 1 ) != '\0' { SWAP }
{
tmp = argv[i];
argv[i] = argv[i+1];
argv[i+1] = tmp;
break;
}
p_1++;
p_2++;
}
}
}
return 0;
}
Related
I need to make a program that will print characters in a word on how frequent it is used. The unique characters will be printed in increasing order (spaces are ignored), if there are ties the character with lower ascii value will be printed first.
For an example if the input is hello world, the letters "h", "e", "w", "r" and "d" are only used once, the character "o" is used twice and the character "l" is used thrice. Since h,e,w,r,d are tie we should sort it into d,e,h,r,w. Then next would be o since it is used twice and then last is l. Thus if the input is hello world the output must be dehrwol. On my current program the problem is that when there are ties, it would not sort it alphabetically so the output is hewrdol instead of dehrwol.
This is the code I have written
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int times[256];
int cmpLetters(const void* a, const void* b)
{
return (times[*(char*)a] > times[*(char*)b]) - (times[*(char*)a] < times[*(char*)b]);
}
int main()
{
char letters[256];
int i, j, k, lnum, t;
char s[1000];
fgets(s, sizeof(s), stdin);
// Init occurrences as 0
memset(times, 0, sizeof(times));
for (i = lnum = 0; s[i] != '\0'; i++)
if (times[s[i]]++ == 0)
letters[lnum++] = s[i];
// Sort letters by number of occurrences
qsort(letters, lnum, sizeof(char), cmpLetters);
char* new = malloc(sizeof(char) * (i + 1));
for (j = k = 0; j < lnum; j++)
for (i = 0; i < times[letters[j]]; i++)
new[k++] = letters[j];
// new[k] = '\0';
for (i = 0; i<lnum; i++)
{
if(letters[i] != '\n' && letters[i] !=' ')
printf("%c",letters[i]);
}
printf("\n\n");
return 0;
}
In this for loop
for (i = lnum = 0; s[i] != '\0'; i++)
if (times[s[i]]++ == 0)
letters[lnum++] = s[i];
you are not checking whether s[i] represents a letter.
The comparison function
int cmpLetters(const void* a, const void* b)
{
return (times[*(char*)a] > times[*(char*)b]) - (times[*(char*)a] < times[*(char*)b]);
}
compares only characters without comparing also their frequencies.
This code snippet
char* new = malloc(sizeof(char) * (i + 1));
for (j = k = 0; j < lnum; j++)
for (i = 0; i < times[letters[j]]; i++)
new[k++] = letters[j];
does not make sense because the array new is not used further in the program. It only produces a memory leak.
The program will be simpler if to introduce a structure that contains two data members that store a letter and its frequency.
Here is a demonstration program.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
struct Pair
{
char c;
size_t n;
};
int cmp( const void *a, const void *b )
{
const struct Pair *p1 = a;
const struct Pair *p2 = b;
int result = ( p2->n < p1->n ) - ( p1->n < p2->n );
if (result == 0)
{
result = ( p2->c < p1->c ) - ( p1->c < p2->c );
}
return result;
}
int main( void )
{
enum { N = 1000} ;
char s[N];
fgets( s, sizeof( s ), stdin );
size_t n = 0;
for (size_t i = 0; s[i] != '\0'; ++i)
{
if (isalpha( ( unsigned char )s[i] ))
{
size_t j = 0;
while (j != i && s[j] != s[i]) ++j;
n += j == i;
}
}
if (n != 0)
{
struct Pair pairs[n];
memset( pairs, 0, n * sizeof( struct Pair ) );
for (size_t i = 0, m = 0; s[i] != '\0'; i++)
{
if (isalpha( ( unsigned char )s[i] ))
{
size_t j = 0;
while (j != m && pairs[j].c != s[i]) ++j;
if (j == m)
{
pairs[m].c = s[i];
++pairs[m].n;
++m;
}
else
{
++pairs[j].n;
}
}
}
qsort( pairs, n, sizeof( *pairs ), cmp );
for (size_t i = 0; i < n; i++)
{
putchar( pairs[i].c );
}
putchar( '\n' );
}
}
The program output might look like
hello world
dehrwol
The problem is simple: take a string, and reverse the position of ONLY letters (lower or uppercase). Leave any special characters where they are. My solution:
char * reverseOnlyLetters(char * S){
int Len = strlen(S);
char *StrBeg, *StrEnd, tempCh;
bool FoundStart = 0, FoundEnd = 0;
StrBeg = S;
StrEnd = S + (Len - 1);
for (int i = 0; i < (Len/2); i++)
{
if (((*StrBeg>= 'A') && (*StrBeg <= 'Z')) || ((*StrBeg >= 'a') && (*StrBeg <= 'z')))
{
FoundStart = 1;
}
else
{
StrBeg++;
}
if (((*StrEnd >= 'A') && (*StrEnd <= 'Z')) || ((*StrEnd >= 'a') && (*StrEnd <= 'z')))
{
FoundEnd = 1;
}
else
{
StrEnd--;
}
if(FoundStart && FoundEnd)
{
tempCh = *StrEnd;
*StrEnd = *StrBeg;
*StrBeg = tempCh;
StrBeg++;
StrEnd--;
FoundStart = 0;
FoundEnd = 0;
}
}
return S;
}
The issue is a testcase like "a-bC-dEf-ghIj" fails; the "E" and the "f" in the middle either don't get swapped at all, or (as I suspect), get swapped, but then get swapped BACK. Anyone see what I'm doing wrong?
Problem is this for (int i = 0; i < (Len/2); i++).
If lenght of string is even, it's ok, but in case it's even it doesn't go through the middle character. E in this "a-bC-dEf-ghIj" case, so it can't switch it with f.
The approach using this for loop
for (int i = 0; i < (Len/2); i++)
is incorrect. Let's assume that the string is "#AB". The result string will look like "#BA"
But using your loop you will have (as Len / 2 is equal to 1)
for (int i = 0; i < 1; i++)
In the first and single iteration of the loop the pointer StrBeg will be incremented
StrBeg++;
because the pointed character is not a letter.
So nothing will be reversed.
The function can be written simpler the following way
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char * reverse_letters( char *s )
{
for ( char *first = s, *last = s + strlen( s ); first < last; ++first )
{
while ( first != last && !isalpha( ( unsigned char )*first ) ) ++first;
while ( last != first && !isalpha( ( unsigned char )*--last ) );
if ( first != last )
{
char c = *first;
*first = *last;
*last = c;
}
}
return s;
}
int main( void )
{
char s[] = "one, two, three";
puts( s );
puts( reverse_letters( s ) );
char s1[] = "#AB";
puts( s1 );
puts( reverse_letters( s1 ) );
}
The program output is
one, two, three
eer, hto, wteno
#AB
#BA
I need to write a function that will count words in a string. For the
purpose of this assignment, a "word" is defined to be a sequence
of non-null, non-whitespace characters, separated from other words by
whitespace.
This is what I have so far:
int words(const char sentence[ ]);
int i, length=0, count=0, last=0;
length= strlen(sentence);
for (i=0, i<length, i++)
if (sentence[i] != ' ')
if (last=0)
count++;
else
last=1;
else
last=0;
return count;
I am not sure if it works or not because I can't test it until my whole program is finished and I am not sure it will work, is there a better way of writing this function?
You needed
int words(const char sentence[])
{
}
(note braces).
For loops go with ; instead of ,.
Without any disclaimer, here's what I'd have written:
See it live http://ideone.com/uNgPL
#include <string.h>
#include <stdio.h>
int words(const char sentence[ ])
{
int counted = 0; // result
// state:
const char* it = sentence;
int inword = 0;
do switch(*it) {
case '\0':
case ' ': case '\t': case '\n': case '\r': // TODO others?
if (inword) { inword = 0; counted++; }
break;
default: inword = 1;
} while(*it++);
return counted;
}
int main(int argc, const char *argv[])
{
printf("%d\n", words(""));
printf("%d\n", words("\t"));
printf("%d\n", words(" a castle "));
printf("%d\n", words("my world is a castle"));
}
See the following example, you can follow the approach : count the whitespace between words .
int words(const char *sentence)
{
int count=0,i,len;
char lastC;
len=strlen(sentence);
if(len > 0)
{
lastC = sentence[0];
}
for(i=0; i<=len; i++)
{
if((sentence[i]==' ' || sentence[i]=='\0') && lastC != ' ')
{
count++;
}
lastC = sentence[i];
}
return count;
}
To test :
int main()
{
char str[30] = "a posse ad esse";
printf("Words = %i\n", words(str));
}
Output :
Words = 4
#include <ctype.h> // isspace()
int
nwords(const char *s) {
if (!s) return -1;
int n = 0;
int inword = 0;
for ( ; *s; ++s) {
if (!isspace(*s)) {
if (inword == 0) { // begin word
inword = 1;
++n;
}
}
else if (inword) { // end word
inword = 0;
}
}
return n;
}
bool isWhiteSpace( char c )
{
if( c == ' ' || c == '\t' || c == '\n' )
return true;
return false;
}
int wordCount( char *string )
{
char *s = string;
bool inWord = false;
int i = 0;
while( *s )
{
if( isWhiteSpace(*s))
{
inWord = false;
while( isWhiteSpace(*s) )
s++;
}
else
{
if( !inWord )
{
inWord = true;
i++;
}
s++;
}
}
return i;
}
Here is one of the solutions. It counts words with multiple spaces or just space or space followed by the word.
#include <stdio.h>
int main()
{
char str[80];
int i, w = 0;
printf("Enter a string: ");
scanf("%[^\n]",str);
for (i = 0; str[i] != '\0'; i++)
{
if((str[i]!=' ' && str[i+1]==' ')||(str[i+1]=='\0' && str[i]!=' '))
{
w++;
}
}
printf("The number of words = %d", w );
return 0;
}
I know this is an old thread, but perhaps someone needs a simple solution, just checks for blank space in ascii and compares current char to that while also makign sure first char is not a space, cheers!
int count_words(string text){
int counter = 1;
int len = strlen(text);
for(int i = 0; i < len; i++){
if(text[i] == 32 && i != 0) {
counter++;
}
}
return counter;}
Here is another solution:
#include <string.h>
int words(const char *s)
{
const char *sep = " \t\n\r\v\f";
int word = 0;
size_t len;
s += strspn(s, sep);
while ((len = strcspn(s, sep)) > 0) {
++word;
s += len;
s += strspn(s, sep);
}
return word;
}
#include<stdio.h>
int main()
{
char str[50];
int i, count=1;
printf("Enter a string:\n");
gets(str);
for (i=0; str[i]!='\0'; i++)
{
if(str[i]==' ')
{
count++;
}
}
printf("%i\n",count);
}
#include<stdio.h>
#include<string.h>
int getN(char *);
int main(){
char str[999];
printf("Enter Sentence: "); gets(str);
printf("there are %d words", getN(str));
}
int getN(char *str){
int i = 0, len, count= 0;
len = strlen(str);
if(str[i] >= 'A' && str[i] <= 'z')
count ++;
for (i = 1; i<len; i++)
if((str[i]==' ' || str[i]=='\t' || str[i]=='\n')&& str[i+1] >= 'A' && str[i+1] <= 'z')
count++;
return count;
}
#include <stdio.h>
int wordcount (char *string){
int n = 0;
char *p = string ;
int flag = 0 ;
while(isspace(*p)) p++;
while(*p){
if(!isspace(*p)){
if(flag == 0){
flag = 1 ;
n++;
}
}
else flag = 0;
p++;
}
return n ;
}
int main(int argc, char **argv){
printf("%d\n" , wordcount(" hello world\nNo matter how many newline and spaces"));
return 1 ;
}
I found the posted question after finishing my function for a C class I'm taking. I saw some good ideas from code people have posted above. Here's what I had come up with for an answer. It certainly is not as concise as other's, but it does work. Maybe this will help someone in the future.
My function receives an array of chars in. I then set a pointer to the array to speed up the function if it was scaled up. Next I found the length of the string to loop over. I then use the length of the string as the max for the 'for' loop.
I then check the pointer which is looking at array[0] to see if it is a valid character or punctuation. If pointer is valid then increment to next array index. The word counter is incremented when the first two tests fail. The function then will increment over any number of spaces until the next valid char is found.
The function ends when null '\0' or a new line '\n' character is found. Function will increment count one last time right before it exit to account for the word preceding null or newline. Function returns count to the calling function.
#include <ctype.h>
char wordCount(char array[]) {
char *pointer; //Declare pointer type char
pointer = &array[0]; //Pointer to array
int count; //Holder for word count
count = 0; //Initialize to 0.
long len; //Holder for length of passed sentence
len = strlen(array); //Set len to length of string
for (int i = 0; i < len; i++){
//Is char punctuation?
if (ispunct(*(pointer)) == 1) {
pointer += 1;
continue;
}
//Is the char a valid character?
if (isalpha(*(pointer)) == 1) {
pointer += 1;
continue;
}
//Not a valid char. Increment counter.
count++;
//Look out for those empty spaces. Don't count previous
//word until hitting the end of the spaces.
if (*(pointer) == ' ') {
do {
pointer += 1;
} while (*(pointer) == ' ');
}
//Important, check for end of the string
//or newline characters.
if (*pointer == '\0' || *pointer == '\n') {
count++;
return(count);
}
}
//Redundent return statement.
count++;
return(count);
}
I had this as an assignment...so i know this works.
The function gives you the number of words, average word length, number of lines and number of characters.
To count words, you have to use isspace() to check for whitespaces. if isspace is 0 you know you're not reading whitespace. wordCounter is a just a way to keep track of consecutive letters. Once you get to a whitespace, you reset that counter and increment wordCount. My code below:
Use isspace(c) to
#include <stdio.h>
#include <ctype.h>
int main() {
int lineCount = 0;
double wordCount = 0;
double avgWordLength = 0;
int numLines = 0;
int wordCounter = 0;
double nonSpaceChars = 0;
int numChars = 0;
printf("Please enter text. Use an empty line to stop.\n");
while (1) {
int ic = getchar();
if (ic < 0) //EOF encountered
break;
char c = (char) ic;
if (isspace(c) == 0 ){
wordCounter++;
nonSpaceChars++;
}
if (isspace(c) && wordCounter > 0){
wordCount++;
wordCounter =0;
}
if (c == '\n' && lineCount == 0) //Empty line
{
break;
}
numChars ++;
if (c == '\n') {
numLines ++;
lineCount = 0;
}
else{
lineCount ++;
}
}
avgWordLength = nonSpaceChars/wordCount;
printf("%f\n", nonSpaceChars);
printf("Your text has %d characters and %d lines.\nYour text has %f words, with an average length of %3.2f ", numChars, numLines, wordCount, avgWordLength);
}
Here is one solution. This one will count words correctly even if there are multiple spaces between words, no spaces around interpuncion symbols, etc. For example: I am,My mother is. Elephants ,fly away.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int countWords(char*);
int main() {
char string[1000];
int wordsNum;
printf("Unesi nisku: ");
gets(string); /*dont use this function lightly*/
wordsNum = countWords(string);
printf("Broj reci: %d\n", wordsNum);
return EXIT_SUCCESS;
}
int countWords(char string[]) {
int inWord = 0,
n,
i,
nOfWords = 0;
n = strlen(string);
for (i = 0; i <= n; i++) {
if (isalnum(string[i]))
inWord = 1;
else
if (inWord) {
inWord = 0;
nOfWords++;
}
}
return nOfWords;
}
this is a simpler function to calculate the number of words
int counter_words(char* a){`
// go through chars in a
// if ' ' new word
int words=1;
int i;
for(i=0;i<strlen(a);++i)
{
if(a[i]==' ' && a[i+1] !=0)
{
++words;
}
}
return words;}
What I need to write:
1.Get a main string from user.
2.Get a subString from a user.
Every match of the subString in the main string, change its letters to uppercase.
Do not use string's functions like strstr.
For example:
main string: abcdeffghfhkfff
sub string: ff
outut: abcdeFFghfhkFFf
Problem: Well, I'm having troubles to continue writing the code after I found one match. for example after I found the first 'f' in the main string, how can I continue check if the second 'f' is adjacent to the found 'f', if not, then try to find another 'f' and check subsequent matches of the subarray until we've found that the length of the substring matches the number of subsequent matches in the string? Here's what I've tried, and in writing the logic of the for loop in 'replaceSubstring' function
#include <stdio.h>
#include <stdlib.h>
#include<conio.h>
#include <string.h>
#define N 101
void replaceSubstring(char *str, char *subStr);
void main()
{
char str[N], subStr[N];
while (strlen(str) != 0 || strlen(subStr) != 0)
{
str[0] = 0;
printf("Enter text: ");
gets(str);
printf("Enter substring: ");
scanf("%s", subStr);
replaceSubstring(str, subStr);
}
}
void replaceSubstring(char *str, char *SubStr)
{
int i, count = 0, j = 0, k = 0;
for (i = 0; i <= strlen(str); i++)
{
if (str[i] == SubStr[k])
{
k++;
count++;
if (count == strlen(SubStr))
{
str[i] -= 32;
}
}
}
puts(str);
getchar();
}
You can use strstr() function to do this more easly, like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 101
void replaceSubstring(char *str, char *subStr);
void main()
{
char str[N], subStr[N];
while (strlen(str) != 0 || strlen(subStr) != 0)
{
str[0] = 0;
printf("Enter text: ");
gets(str);
printf("Enter substring: ");
scanf("%s", subStr);
replaceSubstring(str, subStr);
}
}
void replaceSubstring(char *str, char *SubStr)
{
int i;
char *tmp;
while((tmp = strstr(str, SubStr)) != NULL)
{
for (i = 0; i < strlen(SubStr); i++)
{
tmp[i] -= 32;
}
}
puts(str);
getchar();
}
Here another version of replaceSubstring() function without using strstr() function:
void replaceSubstring(char *str, char *SubStr)
{
int i = 0, found = 1, j = 0, k = 0;
while (i < strlen(str))
{
if (str[i] == SubStr[0])
{
found = 1;
for(k = 0; k < strlen(SubStr); k++)
{
if(str[i+k] != SubStr[k])
{
found = 0;
break;
}
}
if(found)
{
for(k = 0; k < strlen(SubStr); k++)
{
str[i+k] -= 32;
}
i += strlen(SubStr);
}
else
i++;
}
else
i++;
}
puts(str);
getchar();
}
To solve this without using strstr(), i would do something like this:
void replaceSubstring(char *str, char *SubStr)
{
int i = 0, equals = 0, j = 0, k = 0;
for(i=0;i<strlen(str);i++){
j = i;
equals = 1;
k=0;
while(k<strlen(SubStr)&&(equals == 1)){
if(SubStr[k] != str[j]){
equals = 0;
}
k++;
j++;
}
if(equals == 1){
for(j=i;j<i+k;j++){
str[j] -= 32;
}
}
}
puts(str);
getchar();
}
I'm pretty sure this works correctly.
input: abcdeffghfhkfff
substring: ff
output: abcdeFFghfhkFFf
Here is a demonstrative program that shows how the function can be written
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char * replaceSubstring( char *s1, const char *s2 )
{
char *p = s1;
size_t n = strlen( s2 );
while ( ( p = strstr( p, s2 ) ) != NULL )
{
for ( size_t i = 0; i < n; ++i, ++p ) *p = toupper( ( unsigned char )*p );
}
return s1;
}
int main( void )
{
char s[] = "abcdeffghfhkfff";
puts( s );
puts( replaceSubstring( s, "ff" ) );
}
Its output is
abcdeffghfhkfff
abcdeFFghfhkFFf
Take into account that according to the C Standard function main without parameters shall be declared like`
int main( void )
Also it is a bad idea to use "magic" numbers like 32 like in this statement
tmp[i] -= 32;
For example if in the environment there are used EBCDIC characters then this statement will be simply wrong.
Moreover even for ASCII characters this statement is invalid because it is not necessary that original characters are in lower case.
I need to write a function that will count words in a string. For the
purpose of this assignment, a "word" is defined to be a sequence
of non-null, non-whitespace characters, separated from other words by
whitespace.
This is what I have so far:
int words(const char sentence[ ]);
int i, length=0, count=0, last=0;
length= strlen(sentence);
for (i=0, i<length, i++)
if (sentence[i] != ' ')
if (last=0)
count++;
else
last=1;
else
last=0;
return count;
I am not sure if it works or not because I can't test it until my whole program is finished and I am not sure it will work, is there a better way of writing this function?
You needed
int words(const char sentence[])
{
}
(note braces).
For loops go with ; instead of ,.
Without any disclaimer, here's what I'd have written:
See it live http://ideone.com/uNgPL
#include <string.h>
#include <stdio.h>
int words(const char sentence[ ])
{
int counted = 0; // result
// state:
const char* it = sentence;
int inword = 0;
do switch(*it) {
case '\0':
case ' ': case '\t': case '\n': case '\r': // TODO others?
if (inword) { inword = 0; counted++; }
break;
default: inword = 1;
} while(*it++);
return counted;
}
int main(int argc, const char *argv[])
{
printf("%d\n", words(""));
printf("%d\n", words("\t"));
printf("%d\n", words(" a castle "));
printf("%d\n", words("my world is a castle"));
}
See the following example, you can follow the approach : count the whitespace between words .
int words(const char *sentence)
{
int count=0,i,len;
char lastC;
len=strlen(sentence);
if(len > 0)
{
lastC = sentence[0];
}
for(i=0; i<=len; i++)
{
if((sentence[i]==' ' || sentence[i]=='\0') && lastC != ' ')
{
count++;
}
lastC = sentence[i];
}
return count;
}
To test :
int main()
{
char str[30] = "a posse ad esse";
printf("Words = %i\n", words(str));
}
Output :
Words = 4
#include <ctype.h> // isspace()
int
nwords(const char *s) {
if (!s) return -1;
int n = 0;
int inword = 0;
for ( ; *s; ++s) {
if (!isspace(*s)) {
if (inword == 0) { // begin word
inword = 1;
++n;
}
}
else if (inword) { // end word
inword = 0;
}
}
return n;
}
bool isWhiteSpace( char c )
{
if( c == ' ' || c == '\t' || c == '\n' )
return true;
return false;
}
int wordCount( char *string )
{
char *s = string;
bool inWord = false;
int i = 0;
while( *s )
{
if( isWhiteSpace(*s))
{
inWord = false;
while( isWhiteSpace(*s) )
s++;
}
else
{
if( !inWord )
{
inWord = true;
i++;
}
s++;
}
}
return i;
}
Here is one of the solutions. It counts words with multiple spaces or just space or space followed by the word.
#include <stdio.h>
int main()
{
char str[80];
int i, w = 0;
printf("Enter a string: ");
scanf("%[^\n]",str);
for (i = 0; str[i] != '\0'; i++)
{
if((str[i]!=' ' && str[i+1]==' ')||(str[i+1]=='\0' && str[i]!=' '))
{
w++;
}
}
printf("The number of words = %d", w );
return 0;
}
I know this is an old thread, but perhaps someone needs a simple solution, just checks for blank space in ascii and compares current char to that while also makign sure first char is not a space, cheers!
int count_words(string text){
int counter = 1;
int len = strlen(text);
for(int i = 0; i < len; i++){
if(text[i] == 32 && i != 0) {
counter++;
}
}
return counter;}
Here is another solution:
#include <string.h>
int words(const char *s)
{
const char *sep = " \t\n\r\v\f";
int word = 0;
size_t len;
s += strspn(s, sep);
while ((len = strcspn(s, sep)) > 0) {
++word;
s += len;
s += strspn(s, sep);
}
return word;
}
#include<stdio.h>
int main()
{
char str[50];
int i, count=1;
printf("Enter a string:\n");
gets(str);
for (i=0; str[i]!='\0'; i++)
{
if(str[i]==' ')
{
count++;
}
}
printf("%i\n",count);
}
#include<stdio.h>
#include<string.h>
int getN(char *);
int main(){
char str[999];
printf("Enter Sentence: "); gets(str);
printf("there are %d words", getN(str));
}
int getN(char *str){
int i = 0, len, count= 0;
len = strlen(str);
if(str[i] >= 'A' && str[i] <= 'z')
count ++;
for (i = 1; i<len; i++)
if((str[i]==' ' || str[i]=='\t' || str[i]=='\n')&& str[i+1] >= 'A' && str[i+1] <= 'z')
count++;
return count;
}
#include <stdio.h>
int wordcount (char *string){
int n = 0;
char *p = string ;
int flag = 0 ;
while(isspace(*p)) p++;
while(*p){
if(!isspace(*p)){
if(flag == 0){
flag = 1 ;
n++;
}
}
else flag = 0;
p++;
}
return n ;
}
int main(int argc, char **argv){
printf("%d\n" , wordcount(" hello world\nNo matter how many newline and spaces"));
return 1 ;
}
I found the posted question after finishing my function for a C class I'm taking. I saw some good ideas from code people have posted above. Here's what I had come up with for an answer. It certainly is not as concise as other's, but it does work. Maybe this will help someone in the future.
My function receives an array of chars in. I then set a pointer to the array to speed up the function if it was scaled up. Next I found the length of the string to loop over. I then use the length of the string as the max for the 'for' loop.
I then check the pointer which is looking at array[0] to see if it is a valid character or punctuation. If pointer is valid then increment to next array index. The word counter is incremented when the first two tests fail. The function then will increment over any number of spaces until the next valid char is found.
The function ends when null '\0' or a new line '\n' character is found. Function will increment count one last time right before it exit to account for the word preceding null or newline. Function returns count to the calling function.
#include <ctype.h>
char wordCount(char array[]) {
char *pointer; //Declare pointer type char
pointer = &array[0]; //Pointer to array
int count; //Holder for word count
count = 0; //Initialize to 0.
long len; //Holder for length of passed sentence
len = strlen(array); //Set len to length of string
for (int i = 0; i < len; i++){
//Is char punctuation?
if (ispunct(*(pointer)) == 1) {
pointer += 1;
continue;
}
//Is the char a valid character?
if (isalpha(*(pointer)) == 1) {
pointer += 1;
continue;
}
//Not a valid char. Increment counter.
count++;
//Look out for those empty spaces. Don't count previous
//word until hitting the end of the spaces.
if (*(pointer) == ' ') {
do {
pointer += 1;
} while (*(pointer) == ' ');
}
//Important, check for end of the string
//or newline characters.
if (*pointer == '\0' || *pointer == '\n') {
count++;
return(count);
}
}
//Redundent return statement.
count++;
return(count);
}
I had this as an assignment...so i know this works.
The function gives you the number of words, average word length, number of lines and number of characters.
To count words, you have to use isspace() to check for whitespaces. if isspace is 0 you know you're not reading whitespace. wordCounter is a just a way to keep track of consecutive letters. Once you get to a whitespace, you reset that counter and increment wordCount. My code below:
Use isspace(c) to
#include <stdio.h>
#include <ctype.h>
int main() {
int lineCount = 0;
double wordCount = 0;
double avgWordLength = 0;
int numLines = 0;
int wordCounter = 0;
double nonSpaceChars = 0;
int numChars = 0;
printf("Please enter text. Use an empty line to stop.\n");
while (1) {
int ic = getchar();
if (ic < 0) //EOF encountered
break;
char c = (char) ic;
if (isspace(c) == 0 ){
wordCounter++;
nonSpaceChars++;
}
if (isspace(c) && wordCounter > 0){
wordCount++;
wordCounter =0;
}
if (c == '\n' && lineCount == 0) //Empty line
{
break;
}
numChars ++;
if (c == '\n') {
numLines ++;
lineCount = 0;
}
else{
lineCount ++;
}
}
avgWordLength = nonSpaceChars/wordCount;
printf("%f\n", nonSpaceChars);
printf("Your text has %d characters and %d lines.\nYour text has %f words, with an average length of %3.2f ", numChars, numLines, wordCount, avgWordLength);
}
Here is one solution. This one will count words correctly even if there are multiple spaces between words, no spaces around interpuncion symbols, etc. For example: I am,My mother is. Elephants ,fly away.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int countWords(char*);
int main() {
char string[1000];
int wordsNum;
printf("Unesi nisku: ");
gets(string); /*dont use this function lightly*/
wordsNum = countWords(string);
printf("Broj reci: %d\n", wordsNum);
return EXIT_SUCCESS;
}
int countWords(char string[]) {
int inWord = 0,
n,
i,
nOfWords = 0;
n = strlen(string);
for (i = 0; i <= n; i++) {
if (isalnum(string[i]))
inWord = 1;
else
if (inWord) {
inWord = 0;
nOfWords++;
}
}
return nOfWords;
}
this is a simpler function to calculate the number of words
int counter_words(char* a){`
// go through chars in a
// if ' ' new word
int words=1;
int i;
for(i=0;i<strlen(a);++i)
{
if(a[i]==' ' && a[i+1] !=0)
{
++words;
}
}
return words;}