How to create a process for each vowel? - c

I am new at Processes. I read a lot but I didn't really understand how it works. I try to make a process for each vowel in a char string. I have to delete all vowels from that string. I know that I have to use fork, but I don't know how. I tried to write the code, but what I receive was Core Dumped.
#include <unistd.h>
#include <stdio.h>
#include <string.h>
char sir[100];
int vocal(char x)
{
if(x=='a' || x=='e' || x=='i' || x=='o' || x=='u' || x=='A'||
x=='E' || x=='I' || x=='O' || x=='U')
return 1;
return 0;
}
int main(){
printf("Read the text: \n");
read(1,sir,100); // file descriptor is 1;
pid_t a_Process;
for(int i=0;i<strlen(sir);i++)
{
if(vocal(sir[i])==1)
{
a_Process=fork();
for(int j=i;j<strlen(sir)-1;i++)
sir[j]=sir[j+1];
}
}
printf("%s",sir);
return 0;
}
I didn't understand how the child process and everything goes. Thank you very much!

Try this code:
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char sir[100];
int vocal(char x)
{
if (x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u' ||
x == 'A' || x == 'E' || x == 'I' || x == 'O' || x == 'U')
return 1;
return 0;
}
int main()
{
int i, j, pid_status;
printf("Read the text: \n");
// read(1,sir,100); // file descriptor is 1;
fgets(sir, 100, stdin);
pid_t a_Process;
for (i = 0; i < strlen(sir); i++)
{
if (vocal(sir[i]) == 1)
{
printf("detected a vowel\n");
a_Process = fork();
if (a_Process == -1)
{
fprintf(stderr, "Can't fork a process.\n");
return 1;
}
if (a_Process)
{
printf("Starting a new child .... \n");
for (j = i; j < strlen(sir) - 1; j++)
sir[j] = sir[j + 1];
}
// The following statement is needed such that
// child process starts one after the other.
if (waitpid(a_Process, &pid_status, 0) == -1)
{
printf("Error waiting for child process.\n");
}
}
}
printf("%s", sir);
return 0;
}

Related

How to share the pass the value from child to parent in this inifinte unary operations

I am try to implement a program to do this type of calculation in which i have to use only some limited system calls
fork
exec* family
str* family
ato* family
printf, sprintf
round
The program name is double.c and the calculation looks like
./double square 3
output:36 as square(double(3))
I am using exit(result) to returning the result but as the range it is capable of is 0-255 but when the number exeeds from 255 it gives wrong result I have to impement this program just using these system api calls so i think pipe and munmap cannnot be used but how i can return bigger values than using just these functions
What i tried is
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <math.h>
#include <sys/wait.h>
#include <stdlib.h>
#define EPSILON 0.001
double simple_abs(double x)
{
return x > 0 ? x : -x;
}
double simple_sqrt(double x)
{
double previous = 0;
double guess = x;
while (simple_abs(guess - previous) > EPSILON)
{
previous = guess;
guess = previous - (previous * previous - x) / (2 * previous);
}
return guess;
}
int lop(int status) {
return (status >> 8) & 0xff;
}
int square(int n) {
printf("number = %d and square = %d\n", n , n*n);
return n * n;
}
int root(int n) {
return (int) simple_sqrt((double) n);
}
int doubleVal(int n) {
return n * 2;
}
int main(int argc, char *argv[]) {
int value = atoi(argv[argc - 1]);
int result = value;
if (argc > 2){
result = doubleVal(result);
for (int i = 1; i < argc - 1; i++) {
int pid = fork();
if (pid == 0) {
if (*argv[i] == 's' && *(argv[i]+1) == 'q' && *(argv[i]+2) == 'u' && *(argv[i]+3) == 'a' && *(argv[i]+4) == 'r' && *(argv[i]+5) == 'e' && *(argv[i]+6) == '\0'){
result = square(result);
} else if (argv[i][0] == 'r' && argv[i][1] == 'o' && argv[i][2] == 'o' && argv[i][3] == 't' && argv[i][4] == '\0') {
result = root(result);
} else if (argv[i][0] == 'd' && argv[i][1] == 'o' && argv[i][2] == 'u' && argv[i][3] == 'b' && argv[i][4] == 'l' && argv[i][5] == 'e' && argv[i][6] == '\0') {
result = doubleVal(result);
} else {
printf("Unknown operation: %s\n", argv[i]);
exit(1);
}
printf("Child result: %d\n", result);
//return result;
exit(result);
} else {
int status;
wait(&status);
//result = (status >> 8) & 0xff;
result = lop(status);#lop is working as WEXITSTATUS system api
}
}
}
else {
result = doubleVal(result);
}
printf("Result: %d\n", result);
return result;
}
Is there any way to do this to get correct result because when i try ./double square 8 it give wrong result as the result exceeds from 255 .

'Segmentation fault' as user doesn't has an input

I wanted to implement a program that changes the user his DNA-string to a RNA-string. But I have some problems with my code that I don't really understand. My code:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, string argv[])
{
int n = strlen(argv[1]);
if (argc != 2)
{
printf("Usage: ./rna ATGC\n");
return 1;
}
else if (argc == 2 && n >= 4)
{
for (int i = 0; i < n; i++)
{
if (argv[1][i] == 'A' || argv[1][i] == 'a')
{
printf("U");
}
else if (argv[1][i] == 'G' || argv[1][i] == 'g')
{
printf("C");
}
else if (argv[1][i] == 'C' || argv[1][i] == 'c')
{
printf("G");
}
else if (argv[1][i] == 'T' || argv[1][i] == 't')
{
printf("A");
}
}
return 0;
}
if (n <= 3)
{
printf("Invalid DNA\n");
}
}
If the user just runs the program I want to get an output like this:
$ ./rna
Usage: ./rna ATGC
But, I get this and can't really figure out what is wrong.
$ ./rna
Segmentation fault
Your checking the length (argc) of argv after accessing the element that does not exist. You cannot do strlen(argv[1]) before you're sure there is an argv[1]!
int n = strlen(argv[1]);
if there are no command-line arguments it invokes undefined behaviour.
change to:
size_t n = argc > 1 ? strlen(argv[1]) : 0;

"Train crossing mutex problem" - Getting NULL on last 2 lines

Hey I'm having trouble solving a bug that causes some unwanted NULL's to be displayed in my final output. When you run the program enter a string such as 'nnseeeewwwew' into the command line before running.
Here is the code
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
/* mutex */
pthread_mutex_t thisMutex;
/* Condition Variables */
sem_t nQueue, eQueue, sQueue, wQueue;
int nFirst, sFirst, eFirst, wFirst;
int done = 0;
/* Thread Prototypes */
void *bats(void *);
void *checking(void *);
/* Prototypes */
void arrive(int num, char *dir);
void cross();
void leave(int num, char *dir);
void check();
/* Global pointer to argv */
char *directions = NULL;
int main(int argc, char *argv[])
{
int i = 0,
n = 0,
s = 0,
e = 0,
w = 0;
directions = argv[1];
while( argv[1][i] == 'n' || argv[1][i] == 'e' ||
argv[1][i] == 's' || argv[1][i] == 'w' )
{
if(argv[1][i] == 'n'){n++;}
if(argv[1][i] == 's'){s++;}
if(argv[1][i] == 'e'){e++;}
if(argv[1][i] == 'w'){w++;}
i++;
}
pthread_mutex_init(&thisMutex, NULL);
sem_init(&nQueue, 0, n);
sem_init(&sQueue, 0, s);
sem_init(&eQueue, 0, e);
sem_init(&wQueue, 0, w);
nFirst = sFirst = eFirst = wFirst = 0;
pthread_t tid[i];
pthread_t checker;
pthread_create(&checker, NULL, checking, NULL);
for(int j = 0; j < i; j++)
{ pthread_create(&tid[j], NULL, bats, (void*) &j); }
for(int j = 0; j < i; j++)
{ pthread_join(tid[j], NULL); }
done = 1;
pthread_join(checker, NULL);
pthread_mutex_destroy(&thisMutex);
sem_destroy(&nQueue);
sem_destroy(&sQueue);
sem_destroy(&wQueue);
sem_destroy(&eQueue);
return 0;
}
void *checking(void *arg)
{
while( done == 0 )
{
if( nFirst == 1 || sFirst == 1 ||
eFirst == 1 || wFirst == 1 )
check();
}
exit(0);
}
void *bats(void *arg)
{
int index = *(int *)arg;
char *dir;
switch (directions[index])
{
case 'n':
dir = "North";
break;
case 's':
dir = "South";
break;
case 'e':
dir = "East";
break;
case'w':
dir = "West";
break;
}
arrive(index, dir);
leave(index, dir);
_exit(0);
}
/* Functions */
void arrive(int num, char *dir)
{
printf("BAT %d from %s arrives at crossing\n", num, dir);
if(strcmp(dir,"North")== 0)
{
sem_wait(&nQueue);
nFirst = 1;
while(eFirst == 1){ /* do nothing */ }
cross();
nFirst = 0;
sem_post(&nQueue);
}
else if(strcmp(dir,"West")== 0)
{
sem_wait(&wQueue);
wFirst = 1;
while(nFirst == 1){ /* do nothing */ }
cross();
wFirst = 0;
sem_post(&wQueue);
}
else if(strcmp(dir,"South")== 0)
{
sem_wait(&sQueue);
sFirst = 1;
while(wFirst == 1){ /* do nothing */ }
cross();
sFirst = 0;
sem_post(&sQueue);
}
else if(strcmp(dir,"East")== 0)
{
sem_wait(&eQueue);
eFirst = 1;
while(sFirst == 1){ /* do nothing */ }
cross();
eFirst= 0;
sem_post(&eQueue);
}
}
void cross()
{
pthread_mutex_lock(&thisMutex);
sleep(1);
pthread_mutex_unlock(&thisMutex);;
}
void leave(int num, char *dir)
{
printf("BAT %d from %s leaving crossing\n", num, dir);
}
void check()
{
if( nFirst == 1 && sFirst == 1 &&
eFirst == 1 && wFirst == 1 )
{
eFirst = 0;
sleep(1);
eFirst = 1;
}
}
The goal of this assignment is to
BATs arriving from the same direction line up behind the first BAT already at the crossing;
BATs arriving from the right always have the right of way (unless the waiting BAT receives a signal to go);
Deadlock has to be prevented
Starvation has to be prevented
Once you run the code, you'll see the last two lines have 'NULL' for the direction the BAT is arriving from. Need help to solve that issue
Thanks!
Your program has undefined behaviour becasue you are passing pointer to local variable into your thread function. In bats function when dereferencing pointer you may get garbage value:
for(int j = 0; j < i; j++)
{
pthread_create(&tid[j], NULL, bats, (void*) &j);
}
j is local inside for loop.
You could allocate memory to hold value for int
variable:
for(int j = 0; j < i; j++)
{
int* var = malloc(sizeof(int));
*var = j;
pthread_create(&tid[j], NULL, bats, var);
}
remember to free this memory in bats function:
void *bats(void *arg)
{
int index = *(int *)arg;
//...
leave(index, dir);
free (arg); // <--
pthread_exit(NULL); // instead of _exit(0);
}
dir is a char pointer. So you cannot directly use an equality sign like if( dir == "North") What you need is if ((strcmp(dir,"North")== 0)
in the loop below,
while( argv[1][i] == 'n' || argv[1][i] == 'e' ||
argv[1][i] == 's' || argv[1][i] == 'w' )
{
i++;
if(argv[1][i] == 'n'){n++;}
if(argv[1][i] == 's'){s++;}
if(argv[1][i] == 'e'){e++;}
if(argv[1][i] == 'w'){w++;}
}
You are incrementing i first inside the loop. So, for the last element in the array argv[1][i] you are reading junk values. The increment of i should be the last statement in the loop. i.e. after if(argv[1][i] == 'w'){w++;}

C program error:checking if password is valid

I'm trying to create a c program that checks if the password contains at least :
-1 special character
-1 lowercase letter
-1 uppercase letter
-1 digit
when i test it, it doesn't work for some reason i've been trying to figure out my error but i didn't know what was wrong
this is my attemp :
//check password =at least one upper /at least 1 lower/ at least 1 char;
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
void main() {
char pass[20]; //password
int a = 0; //size of the password
int foundChar = 0;
int foundUpper = 0;
int foundLower = 0;
int foundDigit = 0;
int i = 0;
do {
printf("enter your password : ");
scanf("%s", pass);
a = strlen(pass);
if (a = 8) {
if (isdigit(pass[i]) && foundDigit == 0) {
foundDigit = 1;
i++;
} else if (isupper(pass[i]) && foundUpper == 0) {
foundUpper = 1;
i++;
} else if (islower(pass[i]) && foundLower == 0) {
foundLower = 1;
i++;
} else if (foundChar == 0) {
foundChar = 1;
i++;
}
}
}
while ((a < 8) || (foundChar == 0) || (foundDigit == 0) || (foundUpper == 0) || (foundUpper = 0));
}
You are not looping through the password.
After your if (a >= 8) statement, there is no code to loop around and examine the remaining characters in the string.

read char from txt file is wrong

Hello guys please help me to understand something !
I have a txt file and I read different values. I'm doing it successfully but I have an ASCII too, ie. KS98B2
I am trying to read it and store it in a value. Could you please have a look at my code? The word "KS98B2" should be stored at the variable "name". So I declare it in the main as a char. Do you agree?
Inside the "asc" function there is a putchar, and it is printed properly, I checked that, I receive KS98B2.
But, inside the asc function printf gives the value : 84122658
And inside main printf gives the value: 24
Yes, I put %d in printf and name is a char, but how is it possible that the variable is not the same ? How can I make it work? Please help me !
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
FILE *file;
char ch;
int asc(char eow, bool *eof) {
int var = 0;
while((ch=fgetc(file))!=EOF) {
putchar(ch);
if ((ch >= 'A') && (ch <= 'Z')) {
var <<= 4;
var += (ch - 'A' + 65);
}
else if ((ch >= '0') && (ch <= '9')) {
var <<= 4;
var += (ch - '0');
} else if (ch == eow) {
return var;
} else {
puts("Incorrect syntax.\n");
}
}
putchar('\n');
printf("Var inside asc %d\n", var);
}
int main() {
char name;
bool eof = false;
if ((file = fopen("messages.txt", "r")) == NULL) {
puts("WRONG FILE\n");
return 1;
}
while(!feof(file)) {
name= asc('\n', &eof);
printf("Var main: %d\n", name);
}
fclose(file);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
FILE *file;
//char ch;//There is no need to be a global variable
int asc(char eow, bool *eof) {
int var = 0;
int ch;//Type in order to compare the EOF and value must be int
while((ch=fgetc(file))!=EOF) {
if(isupper(ch))
var = var * 36 + (ch - 'A' + 10);
else if(isdigit(ch))
var = var * 36 + (ch - '0');
else if (ch == eow)
return var;
else {
fprintf(stderr, "\nIncorrect syntax.\n");
}
}
*eof = true;
return var;
}
int main(void) {
int name;//It must be int to receive the value of int
bool eof = false;
if ((file = fopen("messages.txt", "r")) == NULL) {
puts("WRONG FILE\n");
return 1;
}
while(!feof(file)) {
name= asc('\n', &eof);
printf("Var main: %d\n", name);
}
fclose(file);
return 0;
}
void putdecimal(int name) {
int i=0;
int var = name;
int array[30];
int cnt = 0;
while(var){
array[cnt++] = var % 36;
var /= 36;
}
for(i = cnt-1; i>=0; i--){
if(array[i]<10)
putchar(array[i] + '0');
else
putchar(array[i] - 10 + 'A');
}
}
Example to store the read characters into an array.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
FILE *file;
char *gasc(int size, char buff[size], char eow){
int i = 0, ch = 0;
while(i < size - 1 && (ch=fgetc(file))!=EOF && ch != eow){
if (isupper(ch) || isdigit(ch)){
buff[i++] = ch;
} else {
fprintf(stderr, "\nIncorrect syntax.\n");
}
}
buff[i] = '\0';
if(i == 0 && ch == EOF)
return NULL;
return buff;
}
int main(void) {
char name[20];
if ((file = fopen("messages.txt", "r")) == NULL) {
puts("WRONG FILE\n");
return 1;
}
//is_eof is no longer necessary to represent NULL return value of gasc instead of EOF.
while(gasc(sizeof(name), name, '\n') != NULL) {
printf("'%s'\n", name);
}
fclose(file);
return 0;
}

Resources