stack with finding character inside string in C language - c

#include <stdio.h>
#include <string.h>
main()
{
int i;
int *b, *z;
char name[30];
char vowel[5] = {'A', 'E', 'I', 'O', 'U'};
char consonants[23] = {'B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','T','V','W','X','Y','Z'};
printf ("input the string: ");
scanf ("%s", name);
printf ("The string is %s\n", name);
for (i=0; name[i]!='\0'; i++){
if
(b=strchr(vowel, name[i]) != NULL) {
printf ("The vowels are: %s\n", b); }
else if
(z=strchr(consonants, name[i]) != NULL) {
printf ("The consonants are: %s\n", z);
}
}
}
I am trying to find how many vowels and consonants in array. That's the only algorithm that our teacher showed us, but it doesn't work. Any one can point me to my mistakes?
I just did one more try, with all your advices,
#include <stdio.h>
#include <string.h>
int main()
{
int vow, cons, i;
char *s, *s1;
char name[30];
char vowel[6] = "AEIOU";
char consonants[21] = "BCDFGHJKLMNPQRSTVWXYZ";
printf ("input the string: ");
scanf ("%s", name);
printf ("The string is %s\n", name);
for (i=0; name[i]!='\0'; i++)
s = strchr(vowel, name[i]);
printf ("The vowels are: %s\n", s);
s1 =strchr(consonants, name[i])) {
printf ("The consonants are: %s\n", s1);
}
return 0;
}
This is how I changed it, with all your advices, what is my other problems? cause still dosen't work fine.
Thanks.
And this is my another version of program
#include <stdio.h>
#include <string.h>
int main()
{
int i;
int counter=0, counter2=0;
char *s;
char name[30];
char vowel[6] = "AEIOU";
char consonants[21] = "BCDFGHJKLMNPQRSTVWXYZ";
printf ("input the string: ");
scanf ("%s", name);
printf ("The string is %s\n", name);
for (i=0; name[i]!='\0'; i++) {
if (s = strchr(vowel, name[i])) {
counter++;
}
else if (s =strchr(consonants, name[i])) {
counter2++;
}
printf ("First counter is %d\n", counter);
printf ("The second counter is %d\n", counter2);
return 0;
}
}
I added counters to count quantity of vowels and consonants, still doesn't work.

strchr() is for searching in strings.
char vowel[] = "AEIOU";
char consonants[] = "BCDFGHJKLMNPQRSTVWXYZ";

#include< stdio.h>
int main()
{
int vowel=0,consonant=0;
printf ("input the string: ");
scanf ("%s", name);
printf ("The string is %s\n", name);
for(int i=0;name[i] !='\0';i++)
{
if( name[i] == 'A' || name[i] == 'E' || name[i] == 'I' || name[i] == 'O' || name[i] == 'U' )
{
vowel++;
}
else
consanant++;
}
printf("%d %d",vowel,consonant);
return 0;
}

When I compile this, I get the following messages:
$ gcc -Wall vc.c
vc.c:4:1: warning: return type defaults to ‘int’ [-Wreturn-type]
vc.c: In function ‘main’:
vc.c:17:8: warning: assignment makes pointer from integer without a cast [enabled by default]
vc.c:17:3: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
vc.c:18:4: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int *’ [-Wformat]
vc.c:20:13: warning: assignment makes pointer from integer without a cast [enabled by default]
vc.c:20:3: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
vc.c:21:4: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int *’ [-Wformat]
vc.c:24:1: warning: control reaches end of non-void function [-Wreturn-type]
So, start by making sure that your return type for main is 'int'
int main(){
and adding a return at the bottom of the function
return 0;
Thereafter, set b and z to be char *s, so that they match the return type of strchr
char *b, *z;
This will get rid of all the warnings.
$ gcc -Wall vc.c
$
Excellent. Now, when we run your program:
$ ./a.out
input the string: aaa
The string is aaa
Segmentation fault
"Segmentation fault" means you're running off the end of an array and reading memory you don't own. Now implement Ignacio Vazquez-Abrams' solution
char vowel[] = "AEIOU";
char consonants[] = "BCDFGHJKLMNPQRSTVWXYZ";
Now your program will run to completion.
$ ./a.out
input the string: AAA
The string is AAA
The vowels are: AEIOU
The vowels are: AEIOU
The vowels are: AEIOU
But it doesn't do much, does it?
So, if you're just trying to count how many vowels and consonants there are, you can just add an integer for each that increments every time the correct type is found and output them at the end:
printf("Vowels:\t%d\nConsonants:\t%d", vowelsFound, consonantsFound);
However, if you're trying to output them as lists, you're going to have much more data manipulation to do. Some links to check out:
Linux Man Page for printf
Linux Man Page for String functions

You have placed the return statement inside the for loop which is preventing it from scanning the entire name array.
When using strchr, you'll also need to convert the current loop character to uppercase for it to match properly since you have defined vowels in uppercase. To use toupper() you need to include ctype.h.
You also don't need to define consonants. What is not a vowel is a consonant.
Here's the code. I've tested it and it works:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
int i;
int counter=0, counter2=0;
char *s;
char name[30];
char vowel[6] = "AEIOU";
printf ("input the string: ");
scanf ("%s", name);
printf ("The string is %s\n", name);
for (i=0; name[i]!='\0'; i++) {
if (strchr(vowel, toupper(name[i])) != NULL) {
counter++;
}
else {
counter2++;
}
}
printf ("First counter is %d\n", counter);
printf ("The second counter is %d\n", counter2);
return 0;
}

Alternatively.
#include <stdio.h>
#include <string.h>
int main() {
int t [256];
int i,c;
int cntw = 0;
int cntc = 0;
const char * vowel="AEIOUaeiou";
const char * consonants="BCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz";
memset(t,0,256);
while (*vowel) { t[*vowel] = 1; ++vowel;}
while (*consonants) { t[*consonants] = 2; ++consonants;}
printf ("Input the text: CTRL-D to end\n");
c = getchar();
while(c >=0) {
switch(t[c]) {
case 1: ++cntw; break;
case 2: ++cntc; break;
}
c=getchar();
}
printf ("Text has %d vowel%s and %d consonant%s\n",
cntw,(cntw>1)?"s":"",
cntc,(cntc>1)?"s":"");
return 0;
}

Related

Command Flow in C, function call after printf

So I have this super simple C code here taking a user input and prints it out followed by a "T-Plus" while loop. In this case I chose a random name for testing "whoa", but the while loop is not called. My question is, why does the "T-Plus: %d\n" while loop print not be called after the printf() function?:
#include <stdio.h>
char getString();
void tcount(void);
int main(void)
{
tcount();
}
void tcount(void)
{
// class scanf user input
printf("%s", getString());
int i = 1;
do
{
printf("T-Plus: %d\n", i);
i++;
} while( i < 51 );
}
char getString()
{
char name;
printf("Please a string name: \n");
scanf("%s", &name);
return name;
}
Now when I run it, this becomes the output:
$ ./namecount
Please a string name:
whoa
but the T-Plus: string does not get called.
I see two issues here:
1) In function getString() you are trying to read/scan a string in a char, you need memory to store the string and a terminating char, so you can use either of these two ways
Use a char array e.g. char name[50]; or
Use a char pointer and
allocate memory using malloc e.g.
char *p_name = malloc(sizeof(char)*50);
2) You are then trying to return this string which is stored in local variable (which would get destroyed as soon as function ends) so you should use the second approach (use malloc) and return the pointer.
So your code would look like:
#include <stdio.h>
#include <stdlib.h>
char * getString();
void tcount(void);
int main(void)
{
tcount();
}
void tcount(void)
{
// class scanf user input
char *p_name = getString();
printf("%s", p_name);
free(p_name);
int i = 1;
do
{
printf("T-Plus: %d\n", i);
i++;
} while( i < 51 );
}
char *getString()
{
char *p_name = malloc(sizeof(char)*50);
printf("Please a string name: \n");
scanf("%s", p_name);
return p_name;
}
Above answer did not work, Okay so I've edited the code like this, it compiles fine. But raises a segmentation fault though.
#include <stdio.h>
#include <stdlib.h>
char * getString();
void tcount(void);
int main(void)
{
tcount();
}
void tcount(void)
{
// class scanf user input
char *name = getString();
printf("%s", name);
free(name);
int i = 1;
do
{
printf("T-Plus: %d\n", i);
i++;
} while( i < 51 );
}
char * getString()
{
char *p_name[50];
printf("Please a string name: \n");
scanf("%49s", (char *) &p_name);
return *p_name;
}
When the program is run, it asks for your input but still raises a Segmentation fault (core dumped).

C: Any Alternative way to get each of string element without using conio.h?

I am trying to write a program to access the name from user and print each of element and it address but can't figure out what happen to my code. If Gcc compiler not support Conio.h library so what should i do? Can I write a program without using conio.h library?.
Please explain it
Here is my code:
//Write a program to find each of string element and it location
#include <stdio.h>
#include<conio.h>
int main(){
char name[10];
int i = 0;
printf("Please enter your name: ");
scanf("%s", name);
while(name[i] != '\0'){
printf("%c is located at %u", name[i], &name[i]);
i++;
}
getch();
return 0;
}
Output: No such file or directory
complination terminated
You should actually display a pointer using the %p format specifier. For more information Correct format specifier to print pointer or address?
#include <stdio.h>
int main(){
char name[10];
int i = 0;
printf("Please enter your name: ");
scanf("%s", name);
while(name[i] != '\0'){
printf("%c is located at %p", name[i], &name[i]);
i++;
}
return 0;
}
Edit: As mentioned in the comment by #David, you should check the return value of scanf also.
if (scanf ("%9s", name) != 1){
fputs ("error: name invalid or EOF\n", stderr);
return 1; }

adding string to character array at specific position giving buffer overflow in c programming

I am very new to c programming, and for a school assignment I need to write a programm that takes a string as input and add the letters “ay” to each word that starts with a consonant at the front of this word. It is hinted that this should be done with strncpy and strcat.
this is the code that I wrote:
#include <stdio.h>
#include <string.h>
int main()
{
char myString[50];
char abc[26] = "bcdfghjklmnpqrstvwxyz";
char strA[50];
char strB[50];
char strC[150];
char ay[3] = "ay";
printf("** Welcome to the Double Dutch game **\nPlease enter a string: ");
scanf(" %[^\n]s", &myString);
int i, j;
for (i=0; myString[i]!='0'; i++) {
for(j=0; abc[j]!='\0'; j++) {
if(abc[j] == myString[i]){
if(myString[i-1] == ' '){
strncpy(strC, &myString[0], i);
strncpy(strB, &myString[i], 40);
strcat(strC, ay);
strcat(strC, strB);
myString[0] = '\0';
strcat(myString, strC);
strC[0] = '\0';
strB[0] = '\0';
}
}
}
}
printf("Result: %s", myString);
}
When i run this code it keeps giving the error * Buffer overlow detected *: /home/a.out terminated. I cannot find the mistake that I made. Hopefully someone can help me.
Thanks
Change this:
scanf(" %[^\n]s", &myString);
to this:
scanf(" %[^\n]", myString);
since %[^\n] conversion modifier is not a modifier for %s, they are independent. As a result, you can discard it.
Tip: Add the size of your array - 1, to prevent a possible buffer overflow, like this: scanf(" %49[^\n]", myString);

the C program does not execute the function outside the main

If I execute the exec() function in another C program as a main function it works perfectly, while if I put it as a function called in the main menu it gives me some warning and the function does not run.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> /* for fork */
#include <sys/types.h> /* for pid_t */
#include <sys/wait.h> /* for wait */
int exec (void) {
char array[100];
char character;
int i = 0;
char* point;
int j = 0;
printf ("Digita una stringa");
printf ("\n");
do {
character = getchar();
array[i] = character;
i++;
}
while (character != '\n');
array[i-1] = '\0';
i = 0;
char* string[100];
char *word = strtok(array, " .");
j = 0;
while (word != NULL) {
printf("%s\n", word);
string[j++] = word; // Increment j
word = strtok(NULL, " .");
}
string[j] = NULL; // Make sure the array is NULL term
printf ("\n");
pid_t pid;
pid = fork();
int status;
if (pid == -1) {
perror("");
}else if (pid == 0) {
execvp(string[0], string); /* execute the command */
fprintf(stderr, "Failed to exec");
exit(1);
}
else {
//.. wait until the child ends
waitpid(-1, &status, 0);
}
return;
}
int read_input (void) {
int choice;
printf("Seleziona una voce dal menu");
do {
printf("\n");
scanf ("%i", &choice);
if (choice > 8 || choice < 1)
printf ("Attenzione, inserisci un valore contemplato dal menu");
}
while ( choice > 8 || choice < 1);
return choice;
}
void main (int argc, char *argv[]) {
printf ("------------------------\n");
printf (" MENU \n");
printf ("------------------------\n");
printf (" \n");
printf ("1) Esecuzione in foreground di un processo\n");
printf ("2) Ctrl -C\n");
printf ("3) Exit\n");
printf ("4) Background\n");
printf ("5) Pipe\n");
printf ("6) Jobs\n");
printf ("7) fg\n");
printf ("8) kill\n");
int menu = read_input();
switch (menu) {
case '1' :
exec ();
break;
case '2' :
//ctrl();
break;
case '3' :
//exit_();
break;
case '4' :
//background();
break;
case '5' :
//pipe();
break;
case '6' :
//jobs();
break;
case '7' :
//fg();
break;
case '8' :
//kill();
break;
}
}
this is the warning:
elaborato.c:31:16: warning: initialization makes pointer from integer without a cast [enabled by default] char *word = strtok(array, " .");
Regarding the problem related to input,
do {
printf("\n");
scanf ("%i", &choice);
if (choice > 8 || choice < 1)
printf ("Attenzione, inserisci un valore contemplato dal menu");
}
while ( choice > 8 || choice < 1);
Once you type an integer and press enter, the scanf() consumes the number and a newline is left in stdin. Next time the loop goes around (assuming input <1 or >8 or something else) scanf gets that newline and it goes on.
add a getchar() after the scanf().
The answer is in the warnings, you should move them from the comment into the question.
elaborato.c:31:16: warning: initialization makes pointer from integer without a cast [enabled by default] char *word = strtok(array, " .");
That means that word, which is a char pointer is being initialized from an integer. Therefore, it seems strtok() is returning an integer... that doesn't sound right.
From the strtok() man page:
#include <string.h>
char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);
That seems right, it returns a char *.... but it also says it's declared in <string.h>... which you aren't including. Since it's not defined, the compiler assumes it as int strtok().
Fix: add the #include <string.h> line.
The problem you are seeing is that of scanf getting skipped.
For more details you can refer here
The call to scanf() after the printf consumes the new-line character and continues without the user having to enter anything.
It reads the very next character from standard in, which is probably a newline character and thus not prompting you for any input.
I'm too tired to comment on the entire code (it is really bad), so I'll just write about the issue in question and how trivially it could be debugged.
First thing to do is to check if we get the number and return to main, hence:
int menu = read_input();
printf("got [%d]\n", menu);
Running this:
[snip]
1
got [1]
So we indeed get to this point.
As such now we check what is this compared to.
int menu = read_input();
printf("got [%d] '1'=[%d]\n", menu, '1');
Let's run:
1
got [1] '1'=[49]
So, menu stores an integer 1, while '1' is a character code for 1 in ascii, which, well, is not an integer 1.
In general I don't see what was the problem with narrowing it down.

Error on the format

11: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[100]’
This is my error....Cant fix it...
#include <stdio.h>
#include <string.h>
int main()
{
char *a;
char *count;
char str[100];
int i ;
printf("\n:enter string for Palindrome test\t");
scanf("%s", &str);
i= strlen(str);
//a=(char *)malloc(i*sizeof(char));
a=&str[0];
count=&str[i-1];
while((*(a++)==*(count--)) && i>=1)
{ i--; }
if(i==0) { printf("\n%s is a palin",str);}
else { printf("\n%s is not palin",str);}
}
Sure you can fix it. Just don't pass the wrong type. Change:
scanf("%s", &str);
To:
scanf("%s", str);
Or, equivalently:
scanf("%s", &str[0]);
You don't always use an ampersand passing arguments to scanf(). If the format string contains either a %c or a %s, it will be looking for a char* type. When you call it with &str, you are calling it with a char** type, or as the compiler says, a char*[100] (a pointer to an array of 100 chars).

Resources