Alphabetize words in sentence in C? - c

I am trying to take words in a sentence and alphabetize them each. it has to be able to differentiate between upper and lower case letters but i am having trouble getting it to do just lower case letters.
If I input one word at a time it will alphabetize it but once I input multiple words it acts weird. If I input "i need help", I expect to receive "i deen ehlp"; instead I receive "i dnee ehlp"
Here is my code:
#include <stdio.h>
#include <string.h>
int main (void)
{
int i, j, k, l=0, m=0, s=0, N=100;
printf("input a sentence with no more than 100 characters \n");
char sentence[N];
scanf("%[^\n]s", sentence);
int slength=strlen(sentence);
printf("Sentence before sorting - %s \n", sentence);
/*capital string keeps track of position of capital letters*/
int capital[slength];
for (i = 0; i < slength-1; i++)
{
for (j = i+1; j < slength; j++)
{
/*make uppercase letters lowercase */
if (sentence[j-1] <=90 && sentence[j-1]>64)
{
capital[l]=i;
sentence[i]=sentence[i]+32;
}
/* skip to next word if a space is detected */
if(sentence[j]==' ')
{
i=j+1;
j=j+2;
}
/*alphabetize loop*/
if (sentence[i] > sentence[j])
{
k = sentence[i];
sentence[i] = sentence[j];
sentence[j] = k;
}
}
}
printf("Sentence after sorting - %s \n", sentence);
return 0;
}

This is a very simple solution.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int letter_sort(const void* a, const void* b)
{
return tolower(*(const char*)a) - tolower(*(const char*)b);
}
char* sentence_sort(char* s)
{
char _[strlen(s)+1];
strcpy(_,s);
for(char* w = strtok(_, " ."); w; w = strtok(NULL, " ."))
{
qsort(w, strlen(w), !!w, letter_sort);
memcpy(s+(w-_), w, strlen(w));
}
return(s);
}
int main(void) {
char sent[101];
printf("Input a sentence with no more than 100 characters \n");
scanf("%[^\n]", sent);
printf("Sentence before sorting: %s\n", sent);
printf("Sentence after sorting: %s\n", sentence_sort(sent));
return 0;
}
Output
Success #stdin #stdout 0s 9424KB
Input a sentence with no more than 100 characters
Sentence before sorting: The quick Brown fox Jumped over the Lazy Dogs.
Sentence after sorting: ehT cikqu Bnorw fox deJmpu eorv eht aLyz Dgos.

Related

Why fgets() doesn't read after the first element?

I am trying to do this programming project in the book i study:
Write a program that sorts a series of words entered by the user:
Enter word: foo
Enter word: bar
Enter word: baz
Enter word: quux
Enter word:
In sorted order: bar baz foo quux
Assume that each word is no more than 20 characters long. Stop reading when the user enters an empty word (i.e., presses Enter without entering a word). Store each word in a dynamically sllocated string, using an array of pointers to keep track of the strings.
After all words have been read, sort the array (using any sorting technique) and then use a loop to print the words in sorted order.
That is what i am trying:
#include <stdio.h>
#include <string.h>
#define MAX_LENGTH 20
int compare ( const void * p, const void * q);
int main (void){
int n;
printf("How many words do you want to write");
scanf("%d", &n);
fflush(stdin);
char * word[n];
for( int i = 0; i < n; i++){
fprintf(stdout , "Waiting for the word:");
if(fgets(word[i] , MAX_LENGTH +1 , stdin) == "\n")
break;
}
qsort((void *)word,n,sizeof(int),compare);
printf("Ordered list is:\n\n");
for( int i = 0; i < n; i++){
fprintf(stdout , "\t %s", word[i]);
}
}
int compare (const void * p, const void * q){
return strcmp( * (char**) p , * (char **) q);
}
Edit : question with italic is solved thanks to fellow coders here. My new issue is i can't read past the first element of array. And program closes itself.
C:\Users\Lenovo\Desktop\ogrenme\ch17>sorting
How many words do you want to write4
Waiting for the word:asd
C:\Users\Lenovo\Desktop\ogrenme\ch17>
And there is one single annoying error that keeps me prevented from completing the exercise and "chill" with rest of this challenging book:
sorting.c:20:5: warning: implicit declaration of function 'qsort' [-Wimplicit-function-declaration]
qsort((void *)word,n,sizeof(int),compare);
I did a small trial (definitely the code could be optimized)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (void) {
int n = 0;
char **string_list;
char *tmp;
//allocate memory for the first element
string_list = (char**)malloc(sizeof(char*)*1);
//infinite loop
while ( 1 ) {
//allocate size of each element to a max of 20 chars
string_list[n] = (char*)malloc(sizeof(char)*20);
printf("Enter word : ");
fgets (string_list[n], 20, stdin);
//remove trailing return carriage
string_list[n][strlen(string_list[n]) - 1] = '\0';
//break the loop here if user enters empty string
if (strlen(string_list[n]) < 1) {
break;
}
//add counter
n++;
//add memory to contain another element
string_list = realloc(string_list, sizeof(char*)*(n+1));
}
printf("\n\nInitial List is:\n");
for (int i=0 ; i<n-1 ; i++) {
printf("%s - ", string_list[i]);
}
printf("%s\n\n", string_list[n-1]);
//sorting the list
for (int i=0; i<n; i++) {
for (int j=0; j<n; j++) {
if (strcmp(string_list[i], string_list[j]) < 0) {
tmp = string_list[i];
string_list[i] = string_list[j];
string_list[j] = tmp;
}
}
}
printf("Sorted List is:\n");
for (int i=0 ; i<n-1 ; i++) {
printf("%s - ", string_list[i], strlen(string_list[i]));
}
printf("%s\n\n", string_list[n-1], strlen(string_list[n-1]));
}
output
$ ./sort
Enter word : foo
Enter word : bar
Enter word : baz
Enter word : quux
Enter word :
Initial List is:
foo - bar - baz - quux
Sorted List is:
bar - baz - foo - quux

How to count characters in a string after splitting the word?

I found this c programming code on https://www.includehelp.com/c-programs/c-program-to-split-string-by-space-into-words.aspx
/*C program to split string by space into words.*/
#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
char splitStrings[10][10]; //can store 10 words of 10 characters
int i,j,cnt;
printf("Enter a string: ");
gets(str);
j=0; cnt=0;
for(i=0;i<=(strlen(str));i++)
{
// if space or NULL found, assign NULL into splitStrings[cnt]
if(str[i]==' '||str[i]=='\0')
{
splitStrings[cnt][j]='\0';
cnt++; //for next word
j=0; //for next word, init index to 0
}
else
{
splitStrings[cnt][j]=str[i];
j++;
}
}
printf("\nOriginal String is: %s",str);
printf("\nStrings (words) after split by space:\n");
for(i=0;i < cnt;i++)
printf("%s\n",splitStrings[i]);
return 0;
}
I had run this code and I have entered the string for an example "The dog is sad" The output will be
The
Dog
Is
Sad
I was wondering if I could count the numbers of the characters after splitting the word; like for an example;
The 3
Dog 3
Is 3
Sad 3
I do not know how to achieve that desired output. Thank you
Your last printf could be:
printf("%s %d ",splitStrings[i], strlen(splitStrings[i]));
You already use strlen() in your first for loop.
Use this modified printf:
/*C program to split string by space into words.*/
#include <stdio.h>
#include <string.h>
int main()
{
char str[100];
char splitStrings[10][10]; //can store 10 words of 10 characters
int i,j,cnt;
printf("Enter a string: ");
gets(str);
j=0; cnt=0;
for(i=0;i<=(strlen(str));i++)
{
// if space or NULL found, assign NULL into splitStrings[cnt]
if(str[i]==' '||str[i]=='\0')
{
splitStrings[cnt][j]='\0';
cnt++; //for next word
j=0; //for next word, init index to 0
}
else
{
splitStrings[cnt][j]=str[i];
j++;
}
}
printf("\nOriginal String is: %s",str);
printf("\nStrings (words) after split by space:\n");
for(i=0;i < cnt;i++)
printf("%s %d ",splitStrings[i],strlen(splitStrings[i]));//modified
return 0;
}

C program to accept a string input and print number of vowels and most repeated vowels in the string

I am learning C so I am doing different C programming challenges one of which is this program. WAP to accept a string input from the user and print the no. vowels and the most repeated vowel in the string.
I am able to calculate and print the number of vowels but I am not able to figure out how should I calculate the most repeated vowel in the string though I can print out directly on the output screen, the most repeated vowel just by having a print statement of vowels[i] inside the inner loop. But I want to calculate the most repeated vowel inside the program itself and then just print it efficiently. I tried different things but nothing worked. Also, I want to keep the code small and efficient. Is there a way to that?
This is what I did so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 150
int main()
{
char Statement[MAX];
char vowels[] = {'a', 'e', 'i', 'o', 'u'};
int i, j;
puts("Enter a simple statement.");
fgets(Statement, 150, stdin);
printf("\nYou entered: %s\n", Statement);
for(i=0; i<=strlen(Statement); i++){
//Converting uppercase input to lowercase
Statement[i] = tolower((unsigned char)Statement[i]);
}
//Calling the function to print no. of
NumberOfVowels(Statement, vowels); vowels
return 0;
}
int NumberOfVowels(char Statement[], char vowels[])
{
int i, j, vowelsAmount = 0, count = 0;
for(i=0; i<5; i++){ //outer loop
for(j=0; j<=strlen(Statement); j++){ //inner loop
if(vowels[i] == Statement[j]){
vowelsAmount++;
printf("%c - ", vowels[i]);
}
}
}
printf("\nTotal number of vowels = %d", vowelsAmount);
return vowelsAmount;
}
You can try any of the below approach ...
Create a struct MAP with key and value as members. Have helper methods that allow you to populate MAP struct with key as vowel and value as no. of occurrences.
Create a 2D array of vowel where row represents the vowels and column no. of occurrences.
Simplest to understand would be creating an array of size 256 (ascii) and keep on increment the value at array[ascii(vowel)] by 1 on each occurrence.
Here is one of the implementation (I have just updated your code so its crude, please work on making it look good and remove redundant prints)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 150
int NumberOfVowels(char Statement[], char vowels[], int counts[])
{
int i, j = 0;
for(j=0; j<strlen(Statement); j++) {
if (Statement[j] == '\0' || Statement[j] == '\n') {
continue;
}
for(i=0; i<5; i++) {
if(vowels[i] == Statement[j]) {
int ascii = (int) vowels[i];
counts[ascii] = counts[ascii] + 1;
}
}
}
for(i=0; i<5; i++) {
int ascii = (int) vowels[i];
printf("%c - %d ", vowels[i], counts[ascii]);
}
printf("\n");
return 0;
}
int main()
{
char Statement[MAX];
char vowels[] = {'a', 'e', 'i', 'o', 'u'};
int counts[256] = {0};
int i, j;
puts("Enter a simple statement.");
fgets(Statement, 150, stdin);
printf("\nYou entered: %s\n", Statement);
for(i=0; i<=strlen(Statement); i++){
//Converting uppercase input to lowercase
Statement[i] = tolower((unsigned char)Statement[i]);
printf("%c ", Statement[i]);
}
//Calling the function to print no. of
NumberOfVowels(Statement, vowels, counts);
return 0;
}
Sample Run
You entered: Hello How are you, I am fine!
h e l l o h o w a r e y o u , i a m f i n e !
a - 2 e - 3 i - 2 o - 3 u - 1

C storing strings into an array

I'm working in a problem from the "C programming a Modern Approach 2nd Edition" text. I want to write a program that writes the smallest and largest words. The program stops accepting inputs when the user enters a 4-letter word.
I'm using an array of strings to solve this but I can't even get my program to store words in it.
#include <stdio.h>
#include <string.h>
#define WORD_LEN 20
int main()
{
char word[WORD_LEN]={0},ch;
char *a[10]={}; //Max 10 words in the array
int i=0,j;
for(;;)
{
printf("Enter a word: ");
fgets(word,WORD_LEN,stdin);
strtok(word, "\n"); //removes newline
a[i] = word;
if(strlen(word) == 4) //if word is 4 characters
break; //break out of loop
i++;
}
for(j=0;j<i;j++) //displaying array
printf("%s\n",a[j]);
return 0;
}
Output:
Enter a word: Analysis
Enter a word: Martin
Enter a word: Jonathan
Enter a word: Dana
Dana
Dana
Dana
Any idea into what I'm doing wrong? Thanks.
As BLUEPIXY mentioned, you are storing same address in all a[i]s. So at the end of the loop, it prints the last output i times.
Solution:
You need to allocate memory for a[i] and copy the strings.
#include <stdio.h>
#include <string.h>
#define WORD_LEN 20
#define MAX_NUM_WORD 10 //Max 10 words in the array
int main()
{
char word[WORD_LEN]={0},ch;
char *a[MAX_NUM_WORD]={0};
int i=0,j;
for(;;)
{
printf("Enter a word: ");
fgets(word,WORD_LEN,stdin);
strtok(word, "\n"); //removes newline
a[i] = malloc(sizeof(char)* (strlen(word)+1)); //1 for '\0'
strcpy(a[i], word);
i++;
if(strlen(word) == 4) //if word is 4 characters
break; //break out of loop
//i++; //You will be missing last 4 letter word if i++ is here.
if(MAX_NUM_WORD <= i) //You can store only MAX_NUM_WORD strings
break;
}
for(j=0;j<i;j++) //displaying array
printf("%s\n",a[j]);
//Your other code.
for(i=0; i<MAX_NUM_WORD && NULL != a[i]; i++)
free(a[i]); //Free the allocated memory.
return 0;
}
Adding to others answers, when using malloc to allocate memory for your strings, it is good to also check the return value of void* pointer returned from it.
Additionally, it is also safe to check the return value of fgets, just to be super safe.
This solution demonstrates these points:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORD_LEN 20
#define MAX_NUM_WORD 10
#define EXIT_LEN 4
int
main(void) {
char word[WORD_LEN];
char *a[MAX_NUM_WORD];
int i = 0, wrd;
while (i < MAX_NUM_WORD) {
printf("Enter a word: ");
if (fgets(word, WORD_LEN, stdin) != NULL) {
word[strlen(word)-1] = '\0';
}
a[i] = malloc(strlen(word)+1);
if (a[i] == NULL) {
fprintf(stderr, "%s\n", "Malloc Problem");
exit(EXIT_FAILURE);
}
strcpy(a[i], word);
i++;
if (strlen(word) == EXIT_LEN) {
break;
}
}
// Print and free, all at once.
for (wrd = 0; wrd < i; wrd++) {
printf("%s\n", a[wrd]);
free(a[wrd]);
a[wrd] = NULL;
}
return 0;
}

Validating User Input String

Here's part of the description of the assignment: The program must stop
accepting input when the user enters the word done. Assume that no word is
more than 20 letters long.
I have to validate that if a word is more than 20 characters thy will get an error message and have to retype again. Also when I type done, the program should end. Im not sure how to write these statements correctly. When I run it and type more then 20 characters it gives me an error - Expression: L("Buffer is too small" &&0)
Here's my Code so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXCHAR 20
int charcount(char []);
int main()
{
char message[MAXCHAR];
int numofchar;
printf("Enter any word to display how many characters that word has.\nA word CANNOT be more than 20 charatcers long.\n");
printf("When you are finished type the word done.\n");
do
{
printf("\nEnter a word: " );
gets_s(message, MAXCHAR);
numofchar = charcount(message);
while ( numofchar > MAXCHAR)
{
printf("The word enterd is more then 20 characters. Try again.\n");
printf("Enter a word: " );
gets_s(message, MAXCHAR);
}
printf("The word %s has %d characters.\n", (message),numofchar);
} while ( (message,MAXCHAR) != 'done');
printf("\nEnd of program.\n");
system ("PAUSE");
return 0;
}
int charcount (char list[])
{
int i, count = 0;
for(i = 0; list[i] != '\0'; i++)
count++;
return(count);
}
To detect an error, you simply need to check the return value of get_s:
http://msdn.microsoft.com/en-us/library/5b5x9wc7%28v=vs.90%29.aspx
int main()
{
char message[MAXCHAR], *s;
int numofchar;
...
do
{
printf("\nEnter a word: " );
s = gets_s(message, MAXCHAR);
if (!s) {
<< some error handling code goes here >>
...

Resources