So, we were given this program in class. "Write a Program in C to count the number of words in a sentence input by the user."
This is what i could come up with, but the number of words is always one less than what is the correct number. My teacher told everyone to just add 1 to the word count before printing it. I think it has a bug, if we don't enter any words, i.e. , press Enter instead of typing,the program suggested by my teacher would still give word count as 1 not 0. Do you know of any way to get proper word count without just adding 1 at the end?
Code:
My code(giving 1 less than correct) :
#include <stdio.h>
#include <string.h>
void main()
{
char s[200];
int count = 0, i;
printf("enter the string\n");
gets(s);
for (i = 0;i<strlen(s);i++)
{
if (s[i] == ' ')
count++;
}
printf("number of words in given string are: %d\n", count);
}
It's just that you're counting spaces, this would also be incorrect if the user ended the string with a bunch of spaces. Try something like this:
#include <stdio.h>
#include <string.h>
void main()
{
char s[200];
int count = 0, i;
int foundLetter = False;
printf("enter the string\n");
gets(s);
for (i = 0;i<strlen(s);i++)
{
if (s[i] == ' ')
foundLetter = False;
else
{
if (foundLetter == False)
count++;
foundLetter = True;
}
}
printf("number of words in given string are: %d\n", count);
}
As other users have commented, your program is susceptible to many other issues depending on the string inputed. The example I have posted assumes that anything that is not a space is a letter and if you find at least one letter, than that's a word. Instead of boolean values you could use a counter to make sure that the word is at least a certain length. You could also check to see that it is not a number or symbol by either writing your own regex function or using an existing one. As others have said there is a lot more you can do with this program, but I've provided an example to point you in the right direction.
You are counting the amount of non-words, but you should be counting the amount of words.
If a word is defined as a sequence of one or more letters, your code might go as:
for every character in the string
if the character is part of a word ( "the car's wheel" is three words )
increase the word count
while the character is part of a word, increment your pointer
One improvement would be to handle lines that contain multiple spaces between words or tabs, while still considering a simple return '\n' as a word. Using getline provides a number of advantages including providing the number of characters read. Here is an example of the approach:
Edit logic simplified:
#include <stdio.h>
int main (void) {
char *line = NULL; /* pointer to use with getline () */
char *p = NULL; /* pointer to parse getline return */
ssize_t read = 0;
size_t n = 0;
int spaces = 0; /* counter for spaces and newlines */
int total = 0; /* counter for total words read */
printf ("\nEnter a line of text (or ctrl+d to quit)\n\n");
while (printf (" input: ") && (read = getline (&line, &n, stdin)) != -1) {
spaces = 0;
p = line;
if (read > 1) { /* read = 1 covers '\n' case (blank line with [enter]) */
while (*p) { /* for each character in line */
if (*p == '\t' || *p == ' ') { /* if space, */
while (*p == '\t' || *p == ' ') /* read all spaces */
p++;
spaces += 1; /* consider sequence of spaces 1 */
} else
p++; /* if not space, increment pointer */
}
}
total += spaces + 1; /* words in line = spaces + 1 */
printf (" chars read: %2zd, spaces: %2d total: %3d line: %s\n",
read, spaces, total, (read > 1) ? line : "[enter]\n");
}
printf ("\n\n Total words read: %d\n\n", total);
return 0;
}
output:
Enter a line of text (or ctrl+d to quit)
input: my
chars read: 3, spaces: 0 total: 1 line: my
input: dog has
chars read: 8, spaces: 1 total: 3 line: dog has
input: fleas and ticks
chars read: 17, spaces: 2 total: 6 line: fleas and ticks
input:
chars read: 1, spaces: 0 total: 7 line: [enter]
input:
chars read: 1, spaces: 0 total: 8 line: [enter]
input: total_words 10
chars read: 17, spaces: 1 total: 10 line: total_words 10
input:
Total words read: 10
//input should be alphanumeric sentences only
#include <bits/stdc++.h>
using namespace std;
int main()
{
freopen("count_words_input.txt","r",stdin); // input file
char c;
long long i,wcount=0,f=0;
i=0;
while(scanf("%c",&c) == 1)
{
if(c == ' ' || c == '\n' || c == '\t' || c == '.')
f=0;
else if(f == 0)
{
wcount++;
f=1;
}
}
printf("%lld\n",wcount);
return 0;
}
Related
I am trying to enter a word, and get how many times the letters were typed.
Say my input is "hello"
my output would be: h = 1, e = 1 l = 2 etc.
I am very close to getting it right, but I have a small issue with this code:
#include <stdio.h>
#include <string.h>
void find_frequency(char s[], int count[]) {
int c = 0;
while (s[c] != '\0') {
if (s[c] >= 'a' && s[c] <= 'z' )
count[s[c]-'a']++;
c++;
}
}
int main()
{
char string[100];
int c, count[26] = {0};
printf("Input a string\n");
gets(string);
find_frequency(string, count);
printf("Character Count\n");
for (c = 0 ; c < 26 ; c++)
if(count[c] > 0)
printf("%c : %d\n", c + 'a', count[c]);
return 0;
}
This code does half of the job, but not all.
It's output is in alphabetical order. How can i change it to give me an output of just the chararray that is input?
As Ry- suggested in this comment you could iterate back over the original string and use the chars as indices into your frequency table. Something like the following:
int len_string = strlen(string);
for (c=0; c<len_string; c++) {
char ch = string[c];
printf("%c: %d, ", ch, count[ch-'a']);
}
This won't completely match your expected output, since this code will output l: 2 twice, but that raises the question:
What is your expected output when you have a string like abba? a:2, b:2? a:1, b:2, a:1? a: 2, b:2, a:2? It's hard to help when you ask such an ambiguous question.
#include <stdio.h>
#include <string.h>
size_t ASCIIfreq[256];
void CountASCII(void *buff, size_t size)
{
unsigned char *charsptr = buff;
memset(ASCIIfreq, 0, sizeof(ASCIIfreq));
while(size--)
{
ASCIIfreq[*charsptr++]++;
}
}
void print(int printall)
{
for(size_t index = 0; index < 256; index++)
{
if(ASCIIfreq[index] || printall)
{
printf("The %03zu (0x%02zx) ASCII - '%c' has occured in the buffer %zu time%c\n",
index, index, (index > 32 && index < 127) ? (char)index : ' ',
ASCIIfreq[index], ASCIIfreq[index] == 1 ? ' ' : 's');
}
}
}
int main()
{
char teststring[] = "i am trying to enter a word, and get how many times the letters were typed. Say my input is \"hello\" my output would be: h = 1, e = 1 l = 2 etc.I am very close to getting it right, but i have a small issue with this code";
CountASCII(teststring, sizeof(teststring));
print(0);
return 0;
}
It's not clear what you mean by:
How can i change it to give me an output of just the chararray that is input?
Because that's exactly what you're doing in any case: Inputting a char array to the function; which is updated with numbers alphabetically; and later output as is.
So I'm guessing that you want to output the counts in the same order that each char was first encountered?
Solution
This will require a bit more work. You could keep a second array tracking the the order each character is encountered within find_frequency. But then that simple clean function starts doing too much.
So consider rather tweaking how you do the output:
void output_frequency(char s[], int count[]) {
int c = 0;
//loop s for the output
while (s[c] != '\0') {
if (s[c] >= 'a' && s[c] <= 'z' ) {
//found a character, report the count only if not reported before
if (count[s[c]-'a'] > 0) {
printf("%c : %d\n", s[c], count[s[c] - 'a']);
count[s[c]-'a'] = 0; //so you don't report this char again
}
}
c++;
}
}
If you are attempting to get an in-order count instead of a count in alphabetical order, you simply need to coordinate the indexes of your count array with the order of characters in your input buffer. To do that, simply loop over all characters in your input buffer and make a second pass counting the number of times the current character occurs. This will give you an in-order count of the number of times each character occurs, e.g.
#include <stdio.h>
#include <string.h>
#define COUNT 128
#define MAXC 1024
int main (void) {
char buf[MAXC] = ""; /* buffer to hold input */
int count[COUNT] = {0}; /* array holding inorder count */
fputs ("enter string: ", stdout); /* prompt for input */
if (!fgets (buf, MAXC, stdin)) { /* read line into buf & validate */
fputs ("error: EOF, no valid input.\n", stderr);
return 1;
}
/* loop over each character not '\n' */
for (int i = 0; buf[i] && buf[i] != '\n'; i++) {
char *p = buf; /* pointer to buf */
size_t off = 0; /* offset from start of buf */
while ((p = strchr (buf + off, buf[i]))) { /* find char buf[i] */
count[i]++; /* increment corresponding index in count */
off = p - buf + 1; /* offset is one past current char */
}
}
for (int i = 0; count[i]; i++) /* output inorder character count */
printf (i ? ", %c: %d" : "%c: %d", buf[i], count[i]);
putchar ('\n'); /* tidy up with new line */
return 0;
}
(note: strchr is used for convenience to simply find the next occurrence of the current character within the string and then off (offset) is used to start the search with the following character until no other matches in the string are found. You can simply use an additional loop over the characters in the buffer if you like.)
Example Use/Output
$ /bin/charcnt_inorder
enter string: hello
h: 1, e: 1, l: 2, l: 2, o: 1
However, this does recount each character and give the count again if the character is duplicated, (e.g. l: 2, l: 2 for each 'l'). Now it is unclear from:
"my output would be: h = 1, e = 1 l = 2 etc."
what you intended in that regard, but with just a little additional effort, you can use a separate index and a separate array to store the first instance of each character (in say a chars[] array) along with the count of each in your count[] array and preserve your inorder count while eliminating duplicate characters. The changes needed are shown below:
#include <stdio.h>
#include <string.h>
#define COUNT 128
#define MAXC 1024
int main (void) {
char buf[MAXC] = "",
chars[COUNT] = ""; /* array to hold inorder chars */
int count[COUNT] = {0};
size_t cdx = 0; /* add count index 'cdx' */
fputs ("enter string: ", stdout);
if (!fgets (buf, MAXC, stdin)) {
fputs ("error: EOF, no valid input.\n", stderr);
return 1;
}
for (int i = 0; buf[i] && buf[i] != '\n'; i++) {
char *p = buf;
size_t off = 0;
chars[cdx] = buf[i]; /* store in chars array */
if (i) { /* if past 1st char */
int n = i;
while (n--) /* simply check all before */
if (buf[n] == buf[i]) /* if matches current */
goto next; /* bail and get next char */
}
while ((p = strchr (buf + off, buf[i]))) {
count[cdx]++; /* increment count at index */
off = p - buf + 1;
}
cdx++; /* increment count index */
next:; /* goto label to jump to */
}
for (int i = 0; count[i]; i++)
printf (i ? ", %c: %d" : "%c: %d", chars[i], count[i]);
putchar ('\n');
return 0;
}
Example Use/Output
$ /bin/charcnt_inorder2
enter string: hello
h: 1, e: 1, l: 2, o: 1
or
$ ./bin/charcnt_inorder2
enter string: amarillo
a: 2, m: 1, r: 1, i: 1, l: 2, o: 1
Now your 'l' is only reported once with the correct count.
Note, in each example you should do additional validation to insure the entire input fit within your buffer, etc... The count (and chars) array were sized at 128 to cover the entire range of ASCII values. Don't skimp on buffer size. If you explicitly limit your input to UPPERcase or lowercase -- then you can limit your count size to 26, otherwise you need to consider the additional characters and punctuation that will be encountered. The same applies to your input buffer. If you anticipate you max input would be 500 chars, double it (generally to next available power of two, no real requirement for powers of two, but you are likely to see it that way).
Bottom line, I'd rather be 10,000 characters too long that one character too short... leading to Undefined Behavior.
Lastly, as mentioned in my comment never, never, never use gets. It is so insecure it has been removed from the C standard library in C11. Use fgets or POSIX getline instead.
Look things over and let me know if you have further questions.
I got this exercise that I haven't been able to solve, the point is to create a program where you type in a text, then the program analyzes each word of the text and counts the vowels of each word, then the program returns in screen the number of words that have 3 or more different vowels, and by different I mean, it doesn't matter if the word has 3 "a", it only count as one (the word has the vowels "a", it doesn't matter how many times), so for example, the word "above" has 3 vowels, the word "been" has 1 vowels, the word "example" has 2 vowels. The vowels can be upper case or lower case, it doesn't matter, and here is the tricky part: It cannot contain any pointers or functions made by us.
what i did was asking the user to enter word by word so the program analyze each word, and then at the end returns the number of words that contain 3 or more vowels, but I feel like there must be an easier way where the user can type a complete paragraph or text, then the program analyzes each word and return the number of words that have 3 or more different vowels.
Anyway, my code is as follows, any suggestions would be appreciated:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
main() {
int vowels, text, words, c, total=0,a=0,e=0,i=0,o=0,u=0;
printf ("How many words does your text has? ");
scanf("%d",&words);
for(c=1;c<=words;c++){
printf("Type your word %d, after that press enter, then press 'control' and 'z' at the same time, and then press enter again: \n", c);
while (EOF != (text=getchar())){
if (text == 'a' || text == 'A'){
a++;
if (a >=2){
a = 1;
}
}
if (text == 'e' || text == 'E'){
e++;
if (e >=2){
e = 1;
}
}
if (text == 'i' || text == 'I'){
i++;
if (i >=2){
i = 1;
}
}
if (text == 'o' || text == 'O'){
o++;
if (o >=2){
o = 1;
}
}
if (text == 'u' || text == 'U'){
u++;
if (u >=2){
u = 1;
}
}
}
vowels = a+e+i+o+u;
if(vowels >=3){
total = total +1;
}
a=0,e=0,i=0,o=0,u=0;
vowels = 0;
}
printf("\n\nThe total of words with 3 or more vowels is: %d", total);
printf("\n");
total=0;
return 0;
}
In order to read and analyze a single word, or a paragraph words to determine the number of words that contain at least three different vowels (of any case), this is one of the rare times when reading input with scanf (using the '%s' format specifier) actually is a reasonable choice.
Recall the '%s' format specifier will read characters up to the first whitespace. That gives you a simple way to read a word at a time from stdin. To end input, the user simply need to generate an EOF by entering ctrl+d (or ctrl+z on windows). This satisfies your paragraph requirement.
For parsing, you can take advantage of converting each character to lower case to simplify checking for vowels. Using a frequency array of 5 elements provides a simple way to track the number of different vowels found in each word. Then a final test to see if the number of vowels found equals the required number is all you need before incrementing your total word count for words with three different vowels.
A simple implementation would be something similar to:
#include <stdio.h>
enum { NREQD = 3, NVOWEL = 5, MAXC = 128 }; /* declare constants */
int main (void) {
char word[MAXC] = ""; /* word buffer */
size_t wordcnt = 0; /* words with 3 different vowels */
printf ("enter a word(s) below, [ctrl+d on blank line to end]\n");
for (;;) {
int vowels[NVOWEL] = {0}, /* frequency array */
vowelcnt = 0, /* vowels per-word */
rtn; /* scanf return */
if ((rtn = scanf ("%127s", word)) == EOF) /* chk EOF */
break;
for (int i = 0; word[i]; i++) { /* loop over each char */
if ('A' <= word[i] && word[i] <= 'Z') /* check upper */
word[i] ^= 'a' - 'A'; /* convert to lower */
switch (word[i]) { /* check if vowel */
case 'a': vowels[0] = 1; break;
case 'e': vowels[1] = 1; break;
case 'i': vowels[2] = 1; break;
case 'o': vowels[3] = 1; break;
case 'u': vowels[4] = 1; break;
}
}
for (int i = 0; i < NVOWEL; i++) /* loop over array */
if (vowels[i]) /* check index */
vowelcnt++; /* increment vowelcnt */
if (vowelcnt >= NREQD) /* do we have at least 3 vowels? */
wordcnt++; /* increment wordcnt */
}
printf ("\nThere are %zu words with %d different vowels.\n",
wordcnt, NREQD);
}
Example Use/Output
$ ./bin/vowelcnt
enter a word(s) below, [ctrl+d on blank line to end]
Everyone Understands That The Dictionary Doesn't Track
Words That Contain Vowels Like It Does Etimology.
There are 4 words with 3 different vowels.
Look things over and let me know if you have further questions.
You can use fgets to read a whole line. I don't know how you define a
paragraph though, do you mean just a long text or a collection of lines? You can
copy & paste multiple lines in the console and if you loop using fgets, then
you get all the lines. But allowing the user to enter multiple lines at once,
it's more tricky, because you should know how many lines the user will input.
That's why I'd say focus on reading the text line by line.
Your solution reads characters by characters and you are ignoring non-vowels.
That's OK, but you are not detecting words like you should do. The for loop
makes no sense, because in the first iteration you enter in a while loop that
is only going to leave when there are no more characters to read from stdin.
So the next iteration of the for loop will not enter the while loop and you
won't be reading anything any more.
You are also repeating too much code, I know you assignment says not to use your
own functions, but this can be improved with a simple look up table by creating
an array of chars using the characters as an index for the array. I'll explain
that in the code.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
int main(void)
{
char line[1024];
// initializing look ups with 0
int lookup_vowels[1 << CHAR_BIT] = { 0 };
// using 'a', 'e' as index for the lookup table
// if you want to know if a character is a vowel,
// lookup_vowels[character] will be 1 if character is
// a vowel, 0 otherwise
lookup_vowels['a'] = lookup_vowels['e'] = lookup_vowels['i'] =
lookup_vowels['o'] = lookup_vowels['u'] = 1;
// for parsing word with strtok
const char *delim = " \t\r\n";
int num_of_words = 0;
printf("Enter some text, to end input press ENTER and then CTRL+D\n");
while(1)
{
if(fgets(line, sizeof line, stdin) == NULL)
break;
// parsing words
char *word = strtok(line, delim);
if(word == NULL)
continue; // the line has only delimiters, ignore it
do {
// will be access with the same principle as the lookup
// table, the character is the index
int present[1 << CHAR_BIT] = { 0 };
size_t len = strlen(word);
for(size_t i = 0; i < len; ++i)
{
// I'll explain later the meaning
int c = tolower(word[i]);
if(lookup_vowels[c])
present[c] = 1; // set the present for a vowel to 1
}
int count = present['a'] + present['e'] + present['i'] + present['o']
+ present['u'];
if(count > 2)
{
printf("'%s' has more than three distinct vowels\n", word);
num_of_words++;
}
} while((word = strtok(NULL, delim)));
}
printf("The number of word with three or more distinct vowels: %d\n", num_of_words);
return 0;
}
So let me quickly explain some of the technique I use here:
The lookup table is an array of size 256 because a char is 8-bit1
value and can have 256 different values (range [0,255]). The idea is that this
array is initialized with 0 overall (int lookup_vowels[1<<CHAR_BIT] = { 0 };) and then
I set to 1 only in 5 places: at the position of the vowels using their
ASCII value as index.
So instead of doing the repeating task if checking
// where c is a char
if(c == 'a' || c == 'A')
a=1;
}
for all vowels, I just can do
int idx = tolower(c);
if(lookup_vowels[idx])
{
// c is a vowel
}
The present variable function similar to the lookup table, here I use the
ASCII code of a vowel as index and set it to 1 if a vowel is present in word.
After scanning all characters in word, I sum all values stored in present.
If the value is greater than 2, then the word has at least 3 or more distinct
vowels and the counter variable is increased.
The function strtok is used to split the line using a defined set of
delimiters, in this case the empty character, tab, carriage return and line
feed. To start parsing the line, strtok must be called with the source string
as the first argument and the delimiters as the second argument. All other
subsequent calls must pass NULL as the first argument. The function returns a
pointer to the next word and returns NULL when no more words have been found.
When a word is found, it calculates the number of distinct vowels and checks if
this number is greater than 2.
fotenotes
1CHAR_BIT defined in limits.h returns the number of bits of byte.
Usually a byte is 8-bit wide, so I could have written 256 instead. But there are
"exotic" architectures where a byte is not 8-bit long, so by doing 1<<CHAR_BIT
I'm getting the correct dimension.
I'm having trouble printing each word in a separate line from an input string in C. The question from the assignment I'm doing states:
Take a sentence as input and print its words in separate lines.
My Code:
#include<stdio.h>
int main()
{
int i;
char s[100];
scanf("%s", s);
for(i=0; s[i]!='\0'; i++)
{
printf("%c", s[i]);
if(s[i]==' ')
{
printf("\n");
}
}
}
Any help would be appreciated.
In your code,
printf("%s", s[i]);
is wrong. Change it to
printf("%c", s[i]);
as, you're trying to print a char value. The conversion specifier for a char is %c.
Note: Always remember, using wrong conversion specifier will lead to undefined behaviour.
Also, while scan()-ing with %s, you cannot read the whole space-delimited input as a single string. From the man page,
%s
Matches a sequence of non-white-space characters; the next pointer must be a pointer to character array that is long enough to hold the input sequence and the terminating null byte ('\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first.
You need to use fgets() to do the job.
That said,
Indent your code properly, make it human-readable.
Chnage scanf("%s", s); to scanf("99%s", s); to avoid possible buffer overflow by putting longer input string than 99 chars.
the proper signature for main() is int main(void).
Rookie, using line-oriented input like fgets or getline is, in general, the proper way to read a line of text. However, when doing simple splitting on a single character, reading a character at a time can be advantageous.
In your case if your task is to read a sentence up to 100 characters and print the words of the sentence out on separate lines, then there is no reason to read the sentence into an array and store the words. You can simply read/print each character until a space is read, then print a newline instead of the space. The reading/printing continues until you reach 100 chars, encounter a newline or EOF:
#include <stdio.h>
#define MAXC 100
int main(void) {
int c = 0;
size_t n = 0;
printf ("\n Enter a sentence.\n\n input: ");
/* read up to 100 characters from stdin, print each word on a line */
while (n < MAXC && (c = getchar ()) != EOF && c != '\n')
{
if (c == ' ')
printf ("\n");
else
printf ("%c", c);
n++;
}
printf ("\n");
if (n == MAXC) /* read and discard remaining chars in stdin */
while ((c = getchar ()) != '\n' && c != EOF);
return 0;
}
Use/Output
$ ./bin/getchar_print_nl_space
Enter a sentence.
input: This is a sentence to split into words.
This
is
a
sentence
to
split
into
words.
Note: if you were going to store all characters, up to 100 (meaning 99 chars and 1 null-terminator), you would need to adjust the length check to n < MAXC - 1 and then null-terminate the array:
char s[MAXC] = {0};
/* read up to 99 characters from stdin into s */
while (n < MAXC - 1 && (c = getchar ()) != EOF && c != '\n')
s[n++] = c;
s[n] = '\0'; /* null-terminate after last character */
if (n == MAXC - 1) /* read and discard remaining chars in stdin */
while ((c = getchar ()) != '\n' && c != EOF);
You would then repeat the logic checking for a space and printing a newline in a for loop:
for (c = 0; c < n; c++)
if (s[c] == ' ')
printf ("\n");
else
printf ("%c", s[c]);
Understanding both manner of input, character-oriented input and line-oriented input will save you time allowing you to match the correct tool to the situation. Here, there is no "more correct" or "less correct" approach, just different ways of doing it.
I think one more way to do this work in a better way is as following.
#include <stdio.h>
#include <string.h>
#define MAX_CHAR 100
int main() {
char s[100],*c;
int i = 0;
scanf("%[^\n]", s);
//Write your logic to print the tokens of the sentence here.
for ( c = s; *c != (int)NULL; c++){
if ( *c == ' '){
*c = '\n';
}
}
printf("%s",s);
return 0;
}
Below code is the answer.
Program also calculates number of space/char and new line.
http://cprograming-char-operation.blogspot.com/2018/07/for-given-statement-print-word-in-each.html
/* Program 1_12 */
/* Count number of line, space and char */
/* Replace a char with specific newline */
/* Add blank space in first input */
#include<stdio.h>
int main()
{
int c,nl,nc,ns,nt;
nl=nc=ns=nt=0;
int d,r, prevd, prevr;
printf("Enter which char to replace :: ");
/* prev is stored before of \n */
while((d = getchar()) != '\n' && (prevd = d));
d = prevd;
printf("Enter word below \n");
while((c=getchar()) != EOF)
{
++nc;
if(c==' ')
++ns;
if(c=='\n')
++nl;
if(c=='\t')
++nt;
/* Replace a char with A */
if(c==d)
putchar('\n');
else
putchar(c);
}
printf("total char=%2d, newline=%2d, space=%2d tabs=%2d\n",nc,nl,ns,nt);
return 0;
}
/* Written by: Prakash Katudia <prakash.katudia#gmail.com> */
gcc ./my_code.c
./a.out
Enter which char to replace :: #space#
Enter word below
hello how are you
hello
how
are
you
#include<stdio.h>
#include<string.h>
int main()
{
char a[1000];
int i,len;
scanf("%[^\n]s",a);
len=strlen(a);
for(i=0;i<len;i++)
{
if(a[i] !=' ')
{
printf("%c", a[i]);
printf("\n");
}
}
}
In this program I have taken a dimensional character array of size[3][4],
as long as I enter a 3 characters for each row it will work well.
For example: if I enter abc abd abd I get the same output but if i enter more letters in the first or second or 3rd row I get an error.
How should I check for null character in 2 dimensional?
# include <stdio.h>
#include <conio.h>
# include <ctype.h>
void main()
{
int i=0;
char name[3][4];
printf("\n enter the names \n");
for(i=0;i<3;i++)
{
scanf( "%s",name[i]);
}
printf( "you entered these names\n");
for(i=0;i<3;i++)
{
printf( "%s\n",name[i]);
}
getch();
}
As pointed out by #SouravGhosh, you can limit your scanf with "%3s", but the problem is still there if you don't flush stdin on each iteration.
You can do this:
printf("\n enter the names \n");
for(i = 0; i < 3; i++) {
int c;
scanf("%3s", name[i]);
while ((c = fgetc(stdin)) != '\n' && c != EOF); /* Flush stdin */
}
How should I chk for null character in 2 dimensional ... [something has eaten the rest part, I guess]
You don't need to, at least not in current context.
The problem is in your approach of allocating memory and putting input into it. Your code has
char name[3][4];
if you enter more that three chars, you'll be overwriting the boundary of allocated memory [considering the space of \0]. You've to limit your scanf() using
scanf("%3s",name[i]);
Note:
change void main() to int main(). add a return 0 at the end.
always check the return value of scanf() to ensure proper input.
EDIT:
As for the logical part, you need to eat up the remainings of the input words to start scanning from the beginning of the next word.
Check the below code [Under Linux, so removed conio.h and getch()]
# include <stdio.h>
# include <ctype.h>
int main()
{
int i=0; char name[3][4];
int c = 0;
printf("\n enter the names \n");
for(i=0;i < 3;i++)
{
scanf( "%3s",name[i]);
while(1) // loop to eat up the rest of unwanted input
{ // upto a ' ' or `\n` or `EOF`, whichever is earlier
c = getchar();
if (c == ' ' || c == '\n' || c == EOF) break;
}
}
printf( "you entered these names\n");
for(i=0;i<3;i++)
{
printf( "%s\n",name[i]);
}
return 0;
}
(Cringing after reading the answers to date.)
First, state the problem clearly. You want to read a line from stdin, and extract three short whitespace separated strings. The stored strings are NUL terminated and at most three characters (excluding the NUL).
#include <stdio.h>
void main(int, char**) {
char name[3][4];
printf("\n enter the names \n");
{
// Read tbe line of input text.
char line[80];
if (0 == fgets(line, sizeof(line), stdin)) {
printf("Nothing read!\n");
return 1;
}
int n_line = strlen(line);
if ('\n' != line[n_line - 1]) {
printf("Input too long!\n");
return 2;
}
// Parse out the three values.
int v = sscanf(line, "%3s %3s %3s", name[0], name[1], name[2]);
if (3 != v) {
printf("Too few values!\n");
return 3;
}
}
// We now have the three values, with errors checked.
printf("you entered these names\n%s\n%s\n%s\n",
name[0], name[1], name[2]
);
return 0;
}
you might consider something on the order of scanf( "%3s%*s",name[i]);
which should, if I recall correctly, take the first three characters (up to a whitespace) into name, and then ignore anything else up to the next white space. This will cover your long entries and it does not care what the white space is.
This is not a perfect answer as it will probably eat the middle entry of A B C if single or double character entries are mode. strtok, will separate a line into useful bits and you can then take substrings of the bits into your name[] fields.
Perhaps figuring out the entire requirement before writing code would be the first step in the process.
I was wondering if I could ask for some help. I am writing a program in C that writes out the number of characters, words, and vowels are in the string(with a few added print statements). I am trying to figure out how to write a code that loops through the string and counts the number of words that contain at least 3 vowels. I feel as if this is a very easy code to write, but it's always the easiest things that seem to elude me. Any help?
Also: Being new to C, how can I get the same results while using the function int vowel_count(char my_sen[]) instead of using the code within my main?
If that's a tad confusing I mean since my main already contains code to count the number of vowels within my input, how can I somewhat transfer said code into this function and still call upon it in main?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define SENTENCE 256
int main(void){
char my_sen[SENTENCE], *s; //String that containts at most 256 as well as a pointer
int words = 1, count = 0,vowel_word = 0; //Integer variables being defined
int i,vowel = 0, length; //More definitions
printf("Enter a sentence: ");//Input sentence
gets(my_sen);//Receives and processes input
length = strlen(my_sen); //Stores the length of the input within length
for(i=0;my_sen[i] != '\0'; i++){
if(my_sen[i]=='a' || my_sen[i]=='e' || my_sen[i]=='i' || my_sen[i]=='o' || my_sen[i]=='u' || //Loop that states if the input contains any of the following
my_sen[i]=='A' || my_sen[i]=='E' || my_sen[i]=='I' || my_sen[i]=='O' || my_sen[i]=='U') //characters(in this case, vowels), then it shall be
{ //stored to be later printed
vowel++;
}
if(my_sen[i]==' ' || my_sen[i]=='!' || my_sen[i]=='.' || my_sen[i]==',' || my_sen[i]==';' || //Similar to the vowel loop, but this time
my_sen[i]=='?') //if the following characters are scanned within the input
{ //then the length of the characters within the input is
length--; //subtracted
}
}
for(s = my_sen; *s != '\0'; s++){ //Loop that stores the number of words typed after
if(*s == ' '){ //each following space
count++;
}
}
printf("The sentence entered is %u characters long.\n", length); //Simply prints the number of characters within the input
printf("Number of words in the sentence: %d\n", count + 1); // Adding 1 to t[he count to keep track of the last word
printf("Average length of a word in the input: %d\n", length/count);//Prints the average length of words in the input
printf("Total Number of Vowels: %d\n", vowel);//Prints the number of vowels in the input
printf("Average number of vowels: %d\n", vowel/count);//Prints the average number of vowels within the input
printf("Number of words that contain at least 3 vowels: %d\n", vowel_word);//Prints number of words that contain at least 3 vowels
return 0;
}
It's not much of a problem.
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int vowel_count(char my_sen[])
{
int wcount = 0; // number of words with 3+ vowel chars
int vcount = 0; // current number of vowel chars in the current word
int i = 0; // index into the string
int ch;
while ((ch = my_sen[i++]) != '\0')
{
if (isspace(ch) || !isalpha(ch))
{
// ch is not an alphabetical char, which can happen either
// before a word or after a word.
// If it's after a word, the running vowel count can be >= 3
// and we need to count this word in.
wcount += vcount >= 3; // add 1 to wcount if vcount >= 3
vcount = 0; // reset the running vowel counter
continue; // skip spaces and non-alphabetical chars
}
if (strchr("aeiouAEIOU", ch) != NULL) // if ch is one of these
{
++vcount; // count vowels
}
}
// If my_sen[] ends with an alphabetical char,
// which belongs to the last word, we haven't yet
// had a chance to process its vcount. We only
// do that in the above code when seeing a non-
// alphabetical char following a word, but the
// loop body doesn't execute for the final ch='\0'.
wcount += vcount >= 3; // add 1 to wcount if vcount >= 3
return wcount;
}
int main(void)
{
char sen[] = "CONSTITUTION: We the People of the United States...";
printf("# of words with 3+ vowels in \"%s\" is %d", sen, vowel_count(sen));
return 0;
}
Output (ideone):
# of words with 3+ vowels in "CONSTITUTION: We the People of the United States..." is 3
Btw, you can alter this function to count all things you need. It already finds where words begin and end and so, simple word counting is easy to implement. And word length, too. And so on.
1) Get the string,
2) use strtok () to get each words seperated by space.
3) Loop through each string by char by char to check if it is vowel.
Please check below code
#include<stdio.h>
#include <string.h>
int count_vowels(char []);
int check_vowel(char);
main()
{
char array[100];
printf("Enter a string\n");
gets(array);
char seps[] = " ";
char* token;
int input[5];
int i = 0;
int c = 0;
int count = 0;
token = strtok (array, seps);
while (token != NULL)
{
c = 0;
c = count_vowels(token);
if (c >= 3) {
count++;
}
token = strtok (NULL, seps);
}
printf("Number of words that contain atleast 3 vowels : %d\n", count);
return 0;
}
int count_vowels(char a[])
{
int count = 0, c = 0, flag;
char d;
do
{
d = a[c];
flag = check_vowel(d);
if ( flag == 1 )
count++;
c++;
}while( d != '\0' );
return count;
}
int check_vowel(char a)
{
if ( a >= 'A' && a <= 'Z' )
a = a + 'a' - 'A'; /* Converting to lower case */
if ( a == 'a' || a == 'e' || a == 'i' || a == 'o' || a == 'u')
return 1;
return 0;
}