If statement is not printing out on my system call - c

I input age as 30 but its not printing my if statement. Can i know why ? Thanks
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#define BUFFSIZE 512
int main()
{
int a;
char *buffer[BUFFSIZE];
write(1,"Please Enter your age: ",23);
a=read(0,*buffer,100);
if(a>21)
write(1,"You are an adult",16);
return 0;
}

This
char *buffer[BUFFSIZE];
declares an array of uninitialized pointers.
This
a=read(0,*buffer,100);
passes the first uninitialized pointer to read, so almost certain returns an error (probably EFAULT).
If you were to fix that (remove the * from both lines), it would still return 3 if you enter 30Enter on the keyboard (3 characters entered)
Fixing all that, you end up with something like:
int main() {
int len;
char buffer[BUFSIZE];
write(1,"Please Enter your age: ",23);
len=read(0,buffer,BUFSIZE-1);
if (len <= 0) {
write(1, "invalid input", 13);
} else {
buffer[len] = '\0';
char *end;
int age = strtol(buffer, &end, 0);
if (*end != '\n')
write(1, "input not a (just) a number", 27);
if(age > 21)
write(1,"You are an adult",16);
}
return 0;
}
There's more stuff you can do with error checking (for example, you might want to ignore spaces on the end of the line, or other questionable input), but this shows where to start.

If you consult the documentation for read you will see that the return value is the number of bytes read. You will need to read the characters in buffer and convert them from a string to an int instead of doing what you are doing.
The C standard library provides functions like atoi and scanf that you can use to convert the string into a number, but it's pretty easy to do it yourself and it's a good exercise for a new C programmer.

Try this out, which changes read for more commonly used fscanf:
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a;
write(1,"Please Enter your age: ",23);
fscanf(stdin, "%d",&a);
if(a>21)
write(1,"You are an adult",16);
return 0;
}

Related

How I can cause a program in C to print only one statement once it encounters a specific condition?

I have been trying to write a C program where the user inputs a command-line argument and the program checks if it is all number digits or not. If that is true, the program simply reprints what the user put in. If that is false and there is at least one non-number mixed in, the program just prints the word "bad" once.
What I have come up so far consists of the program checking each character of the input individually. However, what ends up happening once I put in a mixture of numbers and letters in is that the program would still print the numbers, and then once it gets to printing a letter, it prints the word "bad".
Here's an example:
I put ./program 100x into the terminal
=> Expected result: bad
=> Actual result: 100bad
Here's the code:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main (int argc, string argv[])
{
for(int i = 0; i < strlen(argv[1]); i++) {
if (isdigit(argv[1][i]) != 0) {
printf("%c", argv[1][i]);
return 0;
} else {
printf("bad");
return 1;
}
}
}
First, I don't think your program is doing what your describe because it returns at the first digit encountered. Then, as soon as you see a digit you print it, you want to first check that your input is right and then print it. Taking your implementation, you could modify it like that:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main (int argc, string argv[])
{
// checking input
for(int i = 0; i < strlen(argv[1]); i++) {
if (!(isdigit(argv[1][i]) != 0)) {
printf("bad\n");
return 1;
}
}
// here you know your input is good
// prints input
printf("%s\n", argv[1]);
return 0;
}
Try this one :
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
//for(int i = 0; i < strlen(argv[1]); i++)
{
//if (isdigit(argv[1][i]) != 0)
if(strspn(argv[1], "0123456789" )== strlen(argv[1]))
{
printf("%s", argv[1]);
return 0;
}
else
{
printf("bad");
return 1;
}
}
}
Your logical error is that your program checks one character and immediately prints a digit or a bad message, and so continues with each character. However, you need to try writing an algorithm that first checks the whole string for characters other than numbers. If the algorithm finds at least one character (the result is false), it can close loop by using "break" keyword and print "bad" after. OR if all characters are numbers, you can return the value true and only then print them on the screen.

issue with the using print function unable to print string

when the input is yes in status .the string s does not seem to be able to get printed.
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
int main() {
char name[20],sta[3];
scanf("%s",&name);
scanf("%s",&sta);
if((strcmp("Yes",sta)==0)||(strcmp("yes",sta)==0))
printf("Mrs.%s",name);
if((strcmp("No",sta)==0)||(strcmp("no",sta)==0))
printf("Ms.%s",name);
return 0;
}
I have improved your code based on suggestions in comments.
#include <stdio.h>
#include <string.h>
int main() {
char name[20] = {0},
sta[4] = {0};
scanf("%s", name);
scanf("%s", sta);
if ((strcmp("Yes", sta) == 0) || (strcmp("yes", sta) == 0))
printf("Mrs.%s\n", name);
if ((strcmp("No", sta) == 0) || (strcmp("no", sta) == 0))
printf("Ms.%s\n", name);
return 0;
}
First created sta of size 4 to allow 3 characters of "Yes" to fit in it along with '\0' terminator.
scanf() doesn't require & operator for character strings.
Initialized character array to '\0' (equivalent to ASCII 0).
Removed not required header files and improved formatting a bit.

`read` in C hangs the program when string of length more than 16 entered

I made following program that uses read (system call in C) to get a string from user (of length lesser than 100).
#include<stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
char *s;
int a = read(0, s, 100);
s[a-1] = '\0';
printf("\"%s\" \n read returned: %i; NUL at: %u", s, a, strlen(s));
return 0;
}
What I expected here is, it will get characters until user enters a new-line character. It will then replace that '\n' character by '\0', and print it.
The program works well until I enter 15 or less characters in stdin, but stops working when there are more than 16 characters.
My inputs are as follows:
E:\My Files\Codes>a.exe
1234567890123456
"1234567890123456"
returned = 17; length = 16
E:\My Files\Codes>a.exe
12345678901234567
[My program hanged on this input.]
Why does it only hangs on 16? What is special in this 2^2?
Post script: I used the string.h just to get the length of the string. Once my program starts working good, I will remove it.
I have been testing your code. The faults is: You have a pointer which points nowhere. I solve it reserving and allocating memory for your string (char array). I will post the working code:
#include <stdlib.h> // It is needed for malloc, free, etc...
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
char *s = malloc(100*sizeof(char)); // Allocate memory with malloc
int a = read(0, s, 100);
s[a-1] = '\0';
printf("\"%s\" \n read returned: %i; NUL at: %u", s, a, strlen(s));
free(s); // You need liberate memory before exit
return 0;
}
Also, other way to solve this, without dynamic memory is:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main() {
char s[100]; // s is a char array of 100 elements
int a = read(0, s, 100);
s[a-1] = '\0';
printf("\"%s\" \n read returned: %i; NUL at: %u", s, a, strlen(s));
return 0;
}

String bug in my_shell program

I'm trying to create a simple shell program which execute the program specified in input. There are two main function: scanner() (use strtok to split the input in token) and execute() (fork the process and execute the program).
Unfortunately it doesn't work... I've tried to print string[0] at the end of scanner() and at the beginning of execute(). The first time the output is correct but the second time string[] seems to be modified in a sequence of random numbers so execvp() doesn't work...
I really can't figure out why the values of string[] changes, probably is a very stupid error but I can't see it. I really need your help! Thanks in advice.
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#define DIM 256
int scanner(char*[]);
int execute(char*[]);
int main()
{
char* string[DIM];
scanner(string);
execute(string);
}
/* scan: read the input in token*/
int scanner(char* string[])
{
char input[1024];
char delimit[]=" \t\r\n\v\f";
int i = 0;
if(fgets(input, sizeof input, stdin)) {
string[i] = strtok(input, delimit);
while(string[i]!=NULL){
i++;
string[i]=strtok(NULL,delimit);
}
return 0;
}
return 1;
}
/* execute: execute the command*/
int execute(char* string[])
{
int pid;
printf("%s\n", string[0]);
switch(pid = fork()){
case -1:
return 1;
case 0:
execvp(string[0], string);
return 1;
default:
wait((int*)0);
return 0;
}
}
The string variable input in scanner is a local variable, with storage class "auto". That means that when that function returns, that variable disappears, and the memory it occupied can be re-used for other things. That is unfortunate, since strtok returns pointers into that string variable.

system() does not work

My program reads and stores standard input into a char array cmd and then call system(cmd). I printed out cmd and its content is what I expected. But system(cmd) does not save the content in report.log. I tried with a literal string stored in cmd2, and this time it worked. So what is wrong with system(cmd)?
And I am using Windows 8.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <time.h>
#define MAXLEN 100
char *now(){
time_t t;
time(&t);
return asctime(localtime(&t));
}
int main(int argc, char *argv[])
{
char comment[80];
char cmd[120];
fgets(comment, 80, stdin);
sprintf(cmd, "echo '%s %s' >> report.log", comment, now());
printf("%s", cmd); // content of cmd is what I expect
system(cmd); // does not work, why?
char cmd2 = "echo 'Hello world' >> report.log";
system(cmd2); // work
return 0;
}
Your problem maybe with the excess \ns present in your inputs to sprintf().
fgets() scans and stores the \n from the stdin. You need to get rid of that \n and replace that with a null.
asctime() returns a ctime() return style string, again ended with a newline \n. You need to remove (replace) that too.
You can check the following code for your reference.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#define MAXLEN 100
char *now(){
time_t t;
time(&t);
return asctime(localtime(&t));
}
int main(int argc, char *argv[])
{
char comment[80] = {0};
char cmd[120] = {0};
char * timestring = NULL; //initialize local variables, good practice
fgets(comment, 80, stdin);
comment[ strlen(comment) -1] = 0; //reomve the trailing \n taken by fgtes(), replace by null
timestring = now();
timestring[strlen(timestring)-1] = 0; //remove the \n from ctime() return style string, replace b null
sprintf(cmd, "echo '%s %s' >> report.log", comment, timestring);
printf(">> The string is : %s\n", cmd);
system(cmd); // should work now.. :-)
return 0;
}

Resources