I've just started programming in C, and I have to create a program that counts how many vowels a string has. So far I have this:
int a;
int len = strlen(text)-1
for(a=0;a==len;++a){
if(text[a]=='a'){
++vocals;}
I'm clueless on what's wrong, because it will always print 0. I understand my code as:
starting on the first char until the last one before \0,
compare them to 'a', and if they do equal, add one to the counter.
What's wrong with my code?
Check your tutorials or textbook on the syntax and semantics of the for loop.
It requires a continuation condition, i.e. "loop as long as this is true".
So in your code you should change to:
for(a=0; a<len; ++a)
change this
for(a=0;a==len;++a)
to
for(a=0;a<=len;++a)
first iteration a is not equal to len so it will never enter the loop. you want to iterate over this for loop as long as a is lesser of eual to len, second statement does precisely that.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char* text = "this is a test";
int i, vocals;
int len = strlen(text);
for(i=0;i<len;++i){
if(text[i]=='a'||text[i]=='e'||text[i]=='i'||text[i]=='o'||text[i]=='u')
++vocals;
}
printf("%d\n", vocals);
}
This is a working little program.
Let's look at the main together:
First we declare a char arrays, since you omitted that part i assume your string is correctly formed.
The for loop continues till i becames equal to len. It's a good programming practice to use < or > instead of != or == to increment the strength of the code. Anyway since it's a small program you can even use != which means "Execute the for loop till i becames equal to len"
In the if statement we are just checking if the current character is equal to 'a' or 'e' or 'i' or 'o' or 'u'. As you may now guess || operator means or.
EDIT:
There are a lot of more efficient (and complex) way to do this. For example using Regular Expression. If you're interested there are a lot of good tutorial online, for example this
This code snippet
int a;
int len = strlen(text)-1
for(a=0;a==len;++a){
if(text[a]=='a'){
++vocals;}
does not make great sense.
For example the character 'a' is not the only vowel, the condition a == len is evaluated to true only when the string contains just one character.
You can write a separate function that counts vowels in a string.
Here is a demonstrative program.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
size_t count_vowels( const char *s )
{
const char *vowels = "aeiou";
size_t count = 0;
for ( ; *s; ++s )
{
if ( strchr( vowels, tolower( ( unsigned char )*s ) ) )
{
++count;
}
}
return count;
}
int main(void)
{
char s[] = "Hello Pelput";
printf( "There are %zu vowels in the string\n\"%s\"\n",
count_vowels( s ), s );
return 0;
}
The program output is
There are 4 vowels in the string
"Hello Pelput"
Related
I am new to C programming and trying to make a program to add up the digits from the input like this:
input = 12345 <= 5 digit
output = 15 <= add up digit
I try to convert the char index to int but it dosent seems to work! Can anyone help?
Here's my code:
#include <stdio.h>
#include <string.h>
int main(){
char nilai[5];
int j,length,nilai_asli=0,i;
printf("nilai: ");
scanf("%s",&nilai);
length = strlen(nilai);
for(i=0; i<length; i++){
int nilai1 = nilai[i];
printf("%d",nilai1);
}
}
Output:
nilai: 12345
4950515253
You have two problems with the code you show.
First lets talk about the problem you ask about... You display the encoded character value. All characters in C are encoded in one way or another. The most common encoding scheme is called ASCII where the digits are encoded with '0' starting at 48 up to '9' at 57.
Using this knowledge it should be quite easy to figure out a way to convert a digit character to the integer value of the digit: Subtract the character '0'. As in
int nilai1 = nilai[i] - '0'; // "Convert" digit character to its integer value
Now for the second problem: Strings in C are really called null-terminated byte strings. That null-terminated bit is quite important, and all strings functions (like strlen) will look for that to know when the string ends.
When you input five character for the scanf call, the scanf function will write the null-terminator on the sixth position in the five-element array. That is out of bounds and leads to undefined behavior.
You can solve this by either making the array longer, or by telling scanf not to write more characters into the array than it can actually fit:
scanf("%4s", nilai); // Read at most four characters
// which will fit with the terminator in a five-element array
First of all, your buffer isn't big enough. String input is null-terminated, so if you want to read in your output 12345 of 5 numbers, you need a buffer of at least 6 chars:
char nilai[6];
And if your input is bigger than 5 chars, then your buffer has to be bigger, too.
But the problem with adding up the digits is that you're not actually adding up anything. You're just assigning to int nilai1 over and over and discarding the result. Instead, put int nilai1 before the loop and increase it in the loop. Also, to convert from a char to the int it represents, subtract '0'. All in all this part should look like this:
int nilai1 = 0;
for (i = 0; i < length; i++) {
nilai1 += nilai[i] - '0';
}
printf("%d\n", nilai1);
For starters according to the C Standard the function main without parameters shall be declared like
int main( void )
This character array
char nilai[5];
can not contain a string with 5 digits. Declare the array with at least one more character to store the terminating zero of a string.
char nilai[6];
In the call of scanf
scanf("%s",&nilai);
remove the operator & before the name nilai. And such a call is unsafe. You could use for example the standard function fgets.
This call
length = strlen(nilai);
is redundant and moreover the variable length should be declared having the type size_t.
This loop
for(i=0; i<length; i++){
int nilai1 = nilai[i];
printf("%d",nilai1);
}
entirely does not make sense.
The program can look the following way
#include <stdio.h>
#include <ctype.h>
int main(void)
{
enum { N = 6 };
char nilai[N];
printf( "nilai: ");
fgets( nilai, sizeof( nilai ), stdin );
int nilai1 = 0;
for ( const char *p = nilai; *p != '\0'; ++p )
{
if ( isdigit( ( unsigned char ) *p ) ) nilai1 += *p - '0';
}
printf( "%d\n", nilai1 );
return 0;
}
Its output might look like
nilai: 12345
15
I was told to write a program containing a concatenate function. This program should collect the input strings using fgets (&s1[0], len1+1, stdin)
and then add the two to each other to produce a final product.
My problem falls in that the program compiles but it doesn't display anything on the screen whatsoever, here's what I've got. I couldn't see how I could get it solved without this method of approach.
//function to terminate the program incase reach of 0
int str_len (char s[])
{
int i=0;
while (s[i]= NULL)
++i;
return i+1;
}
char string_cat (char*s1, char*s2)
{
//ADDING THE TWO STRINGS
int str_len(char s[])
char *s1 [80]= {'\0'};
char *s2 [40]= {'\0'};
int len1=str_len(s1);
int len2=str_len(s2);
if (int x=0; len1+len2<80; \0;
return;
}
int main ()
{
char string_cat(char*s1,char*s2)
int str_len(char s[])
//RECIVING THE STRINGS TO ADD
char s1 [80];
char s2 [40];
int i=0;
for (i; i !=0; ++i)
{
printf("What is the first sentence?: ")
fgets(*s1[0], 75+1, stdin);
printf("What is the second sentence?:")
fgets(*s2[0],35+1,stdin);
string_cat(*s1,*s2);
printf("The two sentences added together produce the following: %c",s1 )
}
++i
return 0;
}
aside from the mistake with the for loop that others have pointed out, the while loop in your str_len function is wrong.
you should've used while(s[i] != NULL) instead of s[i] = null. one equal sign, "=", is assignment; two equal signs, "==", is comparisons; and exclamation equals, "!=", means not equal.
Secondly, you reassign your s1 and s2 to different memory locations in your string_cat function with their first character as NULL, "\0". this will always give your str_len a length of 0 if corrected your str_len function as pointed out above, and a length of random number if not corrected based on what's occupying your memory at run time.
thirdly [still in the string_cat function], your if(int x = 0; len1 + len2 < 80; \0; doesn't make sense. you're not doing any concatenations in this function at all.
Sorry for not providing you with the solution as this is a simple exercise. I feel like spoiling you if I were to provide you with the code.
First problem is here
int i=0;
for (i; i !=0; ++i)
You set value 0 to the variable i, and then you check if it does not equal 0. This check does not obviosly pass because i equals 0.
The second problem is also the loop. I can't really get the reason you need the loop it at all, because i is not used at all, exept the increment. So as far as i get it, the loop is not needed at all.
In your code having lot of compilation error. Copy paste the code what you have compiled.
Check this line of code
int i=0;
for (i; i !=0; ++i)
Because of this you are not getting any thing. In for loop you have condition i !=0 which always fail so it's not entering inside the loop.
I am a beginner in C programming and need help! If given the following string as an example:
char prose[ ] = "Ping! King Alfred opened the oven door
To reveal nine perfect cakes.
Oh, what a difference to history
A kitchen timer makes."
How do I write a program that contains a function Cap(&prose[0]) that will convert the first character of each word to a upper case letter?
How do I write a program that contains function int count(&prose[0]) that counts the number of words in the above prose array?
Like all things in computer science, you're given a (relatively) large problem to solve, and the solution requires you to break it into smaller problems until each is solvable... then you do that. Here, you've got two problems (assign upper case at the beginning of each word, and count words) but they're closely related, reducing your work.
Your primary problem is to identify where a word starts (and, naturally, ends); once you can do that, your problems are mostly trivial.
You can probably (within the boundary of your problem) assume that the prose string starts with a word, so you've now only got to identify where words end/resume.
If you #include <ctype.h> you have some help: isalpha(c) indicates if a character (technically an int, but realistically a character) is alphabetic. There are many other character classification functions in there but isalpha() may be all you need.
I assume you know how to iterate through your prose string, but in case you dont:
char *p = prose;
while (*p != '\0') {
...
++p;
}
that's one (of many) ways; as you go through that loop, p will point to the next character. I.e., *p will be the next character.
Now, going through the string, you can use isalpha(*p) to detect if you're looking at an alhpabetic character or not. Combined with whatever you looked at the previous time through the loop, you can decide if you're at a word break... of this isalpha() and the previous one are the same, you've either just started a new word or just ended a word. If you're just starting a word, you can increase your word count and also capitalize this word (by changing the character, such as with *p = toupper(*p); (the toupper() function is also declared in <ctype.h>)
#include <stdio.h>
#include <ctype.h>
void Cap(char *string);
int count(char *string);
int main(void){
char prose[ ] =
"Ping! King Alfred opened the oven door\n"
"To reveal nine perfect cakes.\n"
"Oh, what a difference to history\n"
"A kitchen timer makes.";
printf("before:\n%s\n", prose);
Cap(&prose[0]);
printf("after:\n%s\n", prose);
printf("count of word : %d\n", count(&prose[0]));
return 0;
}
char *NextWordTop(char *string){
static char *p = NULL;
char *ret;
if(string)
p = string;
else if(!p)
return NULL;
while(isspace(*p))++p;
if(*p){
ret = p;
while(!isspace(*p))++p;
} else
ret = p = NULL;
return ret;
}
void Cap(char *str){
char *p;
for(p=NextWordTop(str); p ; p=NextWordTop(NULL))
*p = toupper(*p);
}
int count(char *str){
int c = 0;
char *p;
for(p=NextWordTop(str); p ; p=NextWordTop(NULL))
++c;
return c;
}
Guys i found this caesar cipher code in some site.... But when i run it its showing segmentation fault in online compilers..but in c compiler tat i'm using its showing processor fault... can anyone pls point out the wrong in this code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define caesar(x) rot(13, x)
#define decaesar(x) rot(13, x)
#define decrypt_rot(x, y) rot((26-x), y)
void rot(int c, char *str)
{
int l = strlen(str);
const char *alpha[2] = { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
int i;
for (i = 0; i < l; i++)
{
if (!isalpha(str[i]))
continue;
str[i] = alpha[isupper(str[i])][((int)(tolower(str[i])-'a')+c)%26];
}
}
int main()
{
char str[] = "This is a top secret text message!";
printf("Original: %s\n", str);
caesar(str);
printf("Encrypted: %s\n", str);
decaesar(str);
printf("Decrypted: %s\n", str);
return 0;
}
Your code is correct except for one detail, which might be confusing for a newbie.
It is ok to assume that the function isupper() returns a boolean value 1 or 0, but if you check the documentation it says A value different from zero (i.e., true) if indeed c is an uppercase alphabetic letter. Zero (i.e., false) otherwise.
This and the fact that isupper() is returning an int and not a _Bool is causing the problem.
int isupper ( int c );
When returning true isupper() might return any non_zero value. In my case it returns 8 ( a specific bit-field ). Probably the same in yours.
All you have to do is cast the return of isupper() to _Bool
printf("%d %d" ,(_Bool)isupper('A') , ((int)(tolower(str[i])-'a')+c)%26 ) ;
The problem is most likely your use of isupper as index. It's not guaranteed to return 1 for true values, just that it will return "true" (which may be any non-zero value).
You can solve this by using the ternary expression:
alpha[isupper(str[i]) ? 1 : 0][...]
In the first iteration of your loop, you are trying to write to alpha[256][6], (isupper does not always return 0 or 1)
isupper returns: A value different from zero (i.e., true) if indeed c is an
uppercase alphabetic letter. Zero (i.e., false) otherwise.
alpha[isupper(str[i]) != 0][...] will do the trick
Also note that you should always cast the argument you pass to
isupper(), isalnum(), etc. to unsigned char
I wanted to write a program which counts the occurrences of each letter in a string, then prints one of each letter followed by the count for that letter.
For example:
aabbcccd -
Has 2 a, 2 b, 3 c, and 1 d
So I'd like to convert and print this as:
a2b2c3d1
I wrote code (see below) to perform this count/conversion but for some reason I'm not seeing any output.
#include<stdio.h>
main()
{
char array[]="aabbcccd";
char type,*count,*cp=array;
while(cp!='\0'){
type=*cp;
cp++;
count=cp;
int c;
for(c=1;*cp==type;c++,cp++);
*count='0'+c;
}
count++;
*count='\0';
printf("%s",array);
}
Can anyone help me understand why I'm not seeing any output from printf()?
char array[]="aabbcccd";
char type,*count,*cp=array;
while(cp!='\0'){
*cp is a pointer it's pointing to the address of the start of the array, it will never be == to a char '\0' so it can't leave the loop.
You need to deference the pointer to get what it's pointing at:
while(*cp != '\0') {
...
Also, you have a ; after your for loop, skipping the contents of it:
for(c=1;*cp==type;c++,cp++); <-- this ; makes it not execute the code beneath it
After fixing both of those problems the code produces an output:
mike#linux-4puc:~> ./a.out
a1b1c2cd
Not the one you wanted yet, but that fixes your problems with "printf not functional"
Incidentally, this code has a few other major problems:
You try to write past the end of the string if the last character appears once (you write a '1' where the trailing '\0' was, and a '\0' one character beyond that.
Your code doesn't work if a character appears more than 9 times ('0' + 10 is ':').
Your code doesn't work if a character appears more than 2 times ("dddd" doesn't become "d4"; it becomes "d4dd").
Probably line-buffering. Add a \n to your printf() formatting string. Also your code is very scary, what happens if there are more than 9 of the same character in a row?
1) error correction
while(*cp!='\0'){
and not
while(cp!='\0'){
2) advice
do not use array[] to put in your result user another array to put in your rusel it's more proper and eay
I tried to solve your question quickly and this is my code:
#include <stdio.h>
#define SIZE 255
int main()
{
char input[SIZE] = "aabbcccd";/*input string*/
char output[SIZE]={'\0'};/*where output string is stored*/
char seen[SIZE]={'\0'};/*store all chars already counted*/
char *ip = input;/*input pointer=ip*/
char *op = output;/*output pointer = op*/
char *sp = seen;/*seen pointer=sp*/
char c,count;
int i,j,done;
i=0;
while(i<SIZE && input[i]!='\0')
{
c=input[i];
//don't count if already searched:
done=0;
j=0;
while(j<SIZE)
{
if(c==seen[j])
{
done=1;
break;
}
j++;
}
if(done==0)
{//if i never searched char 'c':
*sp=c;
sp++;
*sp='\0';
//count how many "c" there are into input array:
count = '0';
j=0;
while(j<SIZE)
{
if(ip[j]==c)
{
count++;
}
j++;
}
*op=c;
op++;
*op=count;
op++;
}
i++;
}
*op='\0';
printf("input: %s\n",input);
printf("output: %s\n",output);
return 0;
}
It's not a good code for several reasons(I don't check arrays size writing new elements, I could stop searches at first empty item, and so on...) but you could think about it as a "start point" and improve it. You could take a look at standard library to copy substring elements and so on(i.e. strncpy).