Code with gets() and printf not working - get

So, I'm trying to do this code that says "Hello Mr" or "Hello Mrs" depending on the sex of the user, but when I run the program, it doesn't let me type my name, but why?
Also, I tried to use fgets() but the compiler says "
too few arguments to function 'fgets' "
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void flushstdin()
{
int c;
while((c=getchar())!= '\n' && c != EOF);
}
int main () {
float sex;
char name[60];
printf("\nInform your sex: 1 if you are male, 2 if you are female.");
while(scanf("%f",&sex)!=1 || sex!=1 && sex!=2){ //In case the person typed something different of 1,2.
printf("\nInform a correct value, 1 or 2.\n");
flushstdin();
}if(sex==1){
printf("Inform your name.\n");
gets(name);
printf("\nHello Mr. %s \n",name);
}
if(sex==2){
printf("Inform your name.\n");
gets(name);
printf("\nHello Mrs. %s \n",name);
}
system("pause");
return 1;
}

In this case, when pressing enter to pass the data of whether the user is female or male, the character for enter which is '\n' is still on queue within the input buffer. This occurs when using scanf. This means that the gets() function that follows will read the '\n' character that is still in the buffer without asking the user first.
A simple solution would be adding two lines of code after asking the user's gender that will receive the remaining input(s) in the buffer:
#include <string.h>
#include <math.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void flushstdin() {
int c;
while((c=getchar())!= '\n' && c != EOF);
}
int main () {
float sex;
char name[60];
printf("\nInform your sex: 1 if you are male, 2 if you are female.");
while(scanf("%f",&sex)!=1 || sex!=1 && sex!=2){ //In case the person typed something different of 1,2.
printf("\nInform a correct value, 1 or 2.\n");
flushstdin();
}
//new code, extracts input from buffer until it reads a '\n' character or buffer is empty
char c;
while(( c = getchar()) != '\n' && c != EOF);
//end of new code
if(sex==1){
printf("Inform your name.\n");
gets(name);
printf("\nHello Mr. %s \n",name);
}
if(sex==2){
printf("Inform your name.\n");
gets(name);
printf("\nHello Mrs. %s \n",name);
}
system("pause");
return 1;
}

Related

reverse calls order in fork

Warm greetings,
I wrote these lines which display 4 messages corresponding to 'A', 'B', 'C', and 'D' with a for loop and fork. I would like to reverse the calls (output becomes 'D' 'C' 'B' 'A') by making the parent process wait for the children to execute first.
Initial code (right order from A to D):
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(){
int i;
for(i=0;i<4;i++){
if (fork()){
break;
}
printf("Mon nom est %c. Je viens du processus %d\n",'A'+i,getpid());
}
return(0);
}
My code for the desired output (from D to A):
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(){
int i;
for(i=0;i<4;i++){
if (fork()){
wait(NULL);
break;
}
printf("Mon nom est %c. Je viens du processus %d\n",'A'+i,getpid());
}
return(0);
}
I added wait(NULL) but it doesn't seem to help.
I thank you all in advance!!
Lets trace i between the processes:
P0:i=0; fork(); wait(); exit();
P1: i=0; printf(); i = 1; fork(); wait(); exit();
P2: i=1; printf(); i=2; fork(); wait(); exit();
See the pattern; the parent is always wait()ing and exit()ing without printing. The child prints in the parents place, then becomes the parent of the next generation.
Not to be too picky about style, but even such a small program can benefit from a structured indentation:
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
int i;
for (i=0;i<4;i++) {
if (fork()) {
wait(NULL);
break;
}
printf("Mon nom est %c. Je viens du processus %d\n",'A'+i,getpid());
}
return(0);
}

Why do I get the error message when reading from a FIFO?

On the Introduction to Operative Systems course we're asked to build a client-server model using FIFOs. As client we send a string to the server, the server gets this string and if a file with this name exists it sends back the first line on this file. If the file doesn't exist or it does exist but it happens to be empty, it sends an empty string back.
The problem is that in only works once, i send file1 for example, the server sends back the first line and when I send again file1 or another file's name in the same "session" the printf("First line of the file %s: \n%s\n", name, recived); doesn't happen, it enters into if (read(fifo_serv_client, recived, sizeof(recived)) == -1) { printf("An error occurred.\n"); }.
Any idea on why is this? I tried doing it two times with the same file, so it exists 100% but I still get the same result.
Thank you so much!
Here is the code for the client:
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define BUFSIZE 512
int main()
{
int fifo_client_serv;
char *fifo1 = "fifo_client_serv";
int fifo_serv_client;
char *fifo2 = "fifo_serv_client";
char name[BUFSIZE];
while(1) {
printf("Write the file's name: ");
scanf("%s", name);
/* write str to the FIFO */
fifo_client_serv = open(fifo1, O_WRONLY);
fifo_serv_client = open(fifo2, O_RDONLY);
write(fifo_client_serv, name, sizeof(name));
char recived[BUFSIZE];
if (read(fifo_serv_client, recived, sizeof(recived)) == -1) {
printf("An error occurred.\n");
} else {
printf("First line of the file %s: \n%s\n", name, recived);
close(fifo_client_serv);
close(fifo_serv_client);
}
}
return 0;
}
And here's the code for the server:
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#define BUFSIZE 512
int main()
{
int fifo_client_serv;
char *fifo1 = "fifo_client_serv";
int fifo_serv_client;
char *fifo2 = "fifo_serv_client";
char buf[BUFSIZE];
char line[BUFSIZE];
FILE *file;
/* create the FIFO (named pipe) */
mkfifo(fifo1, 0777);
mkfifo(fifo2, 0777);
printf("Server runnning...\n");
while (1)
{
fifo_client_serv = open(fifo1, O_RDONLY);
fifo_serv_client = open(fifo2, O_WRONLY);
read(fifo_client_serv, buf, BUFSIZE);
if((file = fopen(buf, "r")) == NULL) {
write(fifo_serv_client, "", BUFSIZE);
} else {
fgets(line, BUFSIZE, file);
write(fifo_serv_client, line, BUFSIZE);
}
/* clear buffer and line */
memset(buf, 0, sizeof(buf));
memset(line, 0, sizeof(buf));
close(fifo_client_serv);
close(fifo_serv_client);
unlink(fifo1);
unlink(fifo2);
}
return 0;
}
UPDATE I found why this happens, if I create the fifo inside the while it works fine! I just put mkfifo(fifo1, 0777); mkfifo(fifo2, 0777); first in the while. My question is, is it really necessary to create the FIFO each time I send a text from the client? Can't I just create once the FIFO, do the communication from it and close once I finish?
Can you try to close the file after read/writes in the server file ?
if((file = fopen(buf, "r")) == NULL) {
write(fifo_serv_client, "", BUFSIZE);
fclose(file);
} else {
fgets(line, BUFSIZE, file);
write(fifo_serv_client, line, BUFSIZE);
fclose(file);
}
By the way. Its worth to do error checking on your writes.

What are the different values of rusage structure in getrusage() system call argument?

We use getrusage() system call to find different values of resources it takes two arguments in which the first argument is RUSAGE_SELF or RUSAGE_CHILDREN, the other argument is a structure named rusage. This structure has many elements which can be accessed and give values but what does all of these elements represent?
#include <sys/resource.h>
#include <sys/time.h>
#include <unistd.h>
void print_cpu_time()
{
struct rusage usage;
getrusage (RUSAGE_SELF, &usage);
printf ("CPU time: %ld.%06ld sec user, %ld.%06ld sec system\n",
usage.ru_utime.tv_sec, usage.ru_utime.tv_usec,
usage.ru_stime.tv_sec, usage.ru_stime.tv_usec);
}
int main()
{
print_cpu_time();
}
This program shows values of user time and system time.
What do the other elements of the structure represent and how can they be used in real-life programs, like I am getting value 0 for all other elements of structure if I am trying to access them. So how can I use them to get a value other than 0?
EDIT : I have written a program to find the value of ru_inblock and ru_oublock. It is giving the output as 0 for ru_inblock and 8 for ru_oublock for any input given. Why is this so?
The code is as follow
#include <stdio.h>
#include <sys/resource.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
// a struct to read and write
struct person
{
int id;
char fname[20];
char lname[20];
};
int main ()
{
FILE *outfile;
char ch;
struct person Stu;
int r;
outfile = fopen ("student.dat", "w");
if (outfile == NULL)
{
fprintf(stderr, "\nError opened file\n");
exit (1);
}
do
{
printf("\nEnter Roll : ");
scanf("%d",&Stu.id);
scanf("%*c");
printf("Enter First Name : ");
scanf("%s",Stu.fname);
scanf("%*c");
printf("Enter Last Name : ");
scanf("%s",Stu.lname);
fwrite(&Stu,sizeof(Stu),1,outfile);
printf("\nDo you want to add another data (y/n) : ");
scanf("%*c");
ch = getchar();
}
while(ch=='y' || ch == 'Y');
if(fwrite != 0)
printf("contents to file written successfully !\n");
else
printf("error writing file !\n");
fclose (outfile);
outfile = fopen ("student.dat", "r");
if (outfile == NULL)
{
fprintf(stderr, "\nError opened file\n");
exit (1);
}
struct person input;
while(fread(&input, sizeof(struct person), 1, outfile))
printf ("id = %d name = %s %s\n", input.id,
input.fname, input.lname);
fclose (outfile);
struct rusage r_usage;
r=getrusage(RUSAGE_SELF,&r_usage);
printf("\n%d\n",r);
printf("Memory usage = %ld\n",r_usage.ru_maxrss);
printf("\ninput operations : %ld \n", r_usage.ru_inblock);
printf("\noutput operations : %ld \n", r_usage.ru_oublock);
return 0;
}

C++ portability from Windows to Linux

I have been successfully using the following code in C++ on Windows (via CodeBlocks) and have recently attempted to use the same code on Linux (Ubuntu 18.04) also via CodeBlocks. The code appears to compile fine but fails on execution.
The purpose of the code is to import a comma delimited text file of numbers into an array.
In both Windows and Linux I am using the GNU GCC Compiler.
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <cmath>
#include <iomanip>
#include <ctime>
#include <cstdio>
#include <stdlib.h>
using namespace std;
typedef vector <double> record_t;
typedef vector <record_t> data_t;
istream& operator >> ( istream& ins, record_t& record)
{
record.clear();
string line;
getline( ins, line );
stringstream ss( line );
string field;
while (getline( ss, field, ',' ))
{
stringstream fs( field );
double f = 0.0;
fs >> f;
record.push_back( f );
}
return ins;
}
//-----------------------------------------------------------------------------
istream& operator >> ( istream& ins, data_t& data )
{
data.clear();
record_t record;
while (ins >> record)
{
data.push_back( record );
}
return ins;
}
//-----------------------------------------------------------------------------
int main()
{
data_t data;
ifstream infile( "Import File.txt" );
infile >> data;
if (!infile.eof())
{
cout << "Unsuccessful Import!\n";
return 1;
}
infile.close();
cout << "Your file contains " << data.size()-1 << " records.\n";
return 0;
}
I've checked that the necessary header files exist on Linux and that appears to be the case.
If I comment out the EOF check the console returns the message that
Process returned 49 (0x31)
A snippet of the import file which fails under Linux is:
1138,1139,1137.25,1138.5
1138.25,1138.75,1138.25,1138.5
1138.75,1139,1138.5,1138.75
1138.75,1138.75,1138.25,1138.25
1138.25,1138.25,1137.5,1137.5
1137.5,1138.75,1137.5,1138.5
1138.75,1143.75,1138.75,1143
1143.25,1145.75,1143.25,1144.5
1144.5,1144.75,1143,1143.25
1143.5,1144.5,1143.25,1144.25
Grateful for any help in finding a solution.
That return 4321; in main reports an unsuccessful return code to the OS. Only 0 return code (aka EXIT_SUCCESS) is considered successful.
Change it to return 0 or completely remove that return statement (in C++ main has implicit return 0).

debugging server's cgi program

i am trying to make a webserver in C which can handle request to dynamic contents.
the webserver part is finish already. i'm trying to execute the following command:
http://localhost:1601/cgi-bin/test?3&7
with the code of program test is as follow:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#include <fcntl.h>
#include <errno.h>
#include <wordexp.h>
#define MAXLINE 300
int main(int narg, char * arg[]) {
char *buf, *p;
char arg1[MAXLINE], arg2[MAXLINE], content[MAXLINE];
int n1=0, n2=0;
/* Extract the two arguments */
if ((buf = getenv("QUERY_STRING")) != NULL) {
p = strchr(buf, '&');
*p = '\0';
strcpy(arg1, buf);
strcpy(arg2, p+1);
n1 = atoi(arg1);
n2 = atoi(arg2);
}
/* Make the response body */
sprintf(content, "Welcome to add.com: ");
sprintf(content, "%sTHE Internet addition portal.\r\n<p>", content);
sprintf(content, "%sThe answer is: %d + %d = %d\r\n<p>",
content, n1, n2, n1 + n2);
sprintf(content, "%sThanks for visiting!\r\n", content);
/* Generate the HTTP response */
printf("Content-length: %d\r\n", (int)strlen(content));
printf("Content-type: text/html\r\n\r\n");
printf("%s", content);
if (fork()==0) {
printf("asdfagloiauergauhfgaiudfhg");
execvp("ls",arg);
printf("child of adder error");
}
printf("%s", content);
fflush(stdout);
exit(0);
}
/* $end adder */
It run well. However, i wonder why the child code (the line printf("asdfagloiauergauhfgaiudfhg"); and execvp) didn't print out to the webserver's output. although everything else in test output correctly.
For starters you set the Content-length header to the length of the content, then sent the content, then sent more data in both threads. The browser is within its rights to ignore everything after content-length bytes in the output stream.

Resources