I'm writing a program that needs to use only the Unix system calls open, read and write to get and print data!The problem is that the program doesn't allow me to input the marital status of the first student!
Am I missing something?
Here is the code:

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>

struct Student
{
  char name[21];
  char id[11];
  char DOB[9];
  char gender[2];
  char status[2];
};

struct Student myArr[5];//An array of Struct Student  
int main()
{
  int x, y, z;
  char newline[2] = { "\n" };
  char sep[5] = { "    " };
  char buf1[] = { "Please enter the name of the student's:" };
  char buf2[] = { "Please enter the student's id:" };
  char buf3[] = { "Please enter the student's DOB:" };
  char buf4[] = { "Please enter the student's gender:" };
  char buf5[] = { "Please enter the student's marital status:" };

  //O_CREAT requires a third argument the mode which specifies the access permission bits
  //S_IRWXU indicates that the user has read, write and execute permissions
  x = open( "/home/user/Desktop/Labsheets/Labsheet4/input.dat", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU );
  //fd 0 is standard input and 1 is standard output
  //will read from standard input and place data in the buffer
  //read return number of bytes read
  int i;
  for( i = 0; i < 5; i++ )
  {
    write( 1, buf1, strlen(buf1) );
    read( 0, myArr[i].name, 20 );//read from standard input and place data in buffer
    write( 1, buf2, strlen(buf2) );;
    read( 0, myArr[i].id, 10 );
    write( 1, buf3, strlen(buf3) );
    read( 0, myArr[i].DOB, 9 );
    write( 1, buf4, strlen(buf4) );
    read( 0, myArr[i].gender, 1 );
    write( 1, buf5, strlen(buf5) );
    read( 0, myArr[i].status, 1 );
  }
  for(  i = 0; i < 5; i++ )
  {
    write( x, myArr[i].name, strlen(myArr[i].name) );
    write( x, sep, 4 );
    write( x, myArr[i].id, strlen(myArr[i].id) );
    write( x, sep, 4 );
    write( x, myArr[i].DOB, strlen(myArr[i].DOB) );
    write( x, sep, 4 );
    write( x, myArr[i].gender, strlen(myArr[i].gender) );
    write( x, sep, 4 );
    write( x, myArr[i].status, strlen(myArr[i].status) );
    write( x, newline, 4 );
  
  }
 
  return 0;
}

Edited 7 Years Ago by DARK_BYTE: n/a

its because u r taking only one character in the read for the gender. After u enter m/f when u hit enter key it actually takes the '\n' as an input for the next read statement. Hence the next read() is skipped.

write( 1, buf4, strlen(buf4) );
read( 0, myArr[i].gender, 1 );   
write( 1, buf5, strlen(buf5) );
read( 0, myArr[i].status, 1 );

correct your code as

write( 1, buf4, strlen(buf4) );
read( 0, myArr[i].gender, 2 );// replaced 1 with 2   
write( 1, buf5, strlen(buf5) );
read( 0, myArr[i].status, 2 );// replaced 1 with 2

Also increase the buffer size for gender and status by 1.

it will work...........

Edited 7 Years Ago by dkalita: n/a

This works..maybe you can figure out why

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>

struct Student
{
  char name[21];
  char id[11];
  char DOB[9];
  char gender[2];
  char status[2];
};

struct Student myArr[5];//An array of Struct Student  
int main()
{
  int x, y, z;
	char dumb[1];
  char newline[2] = { "\n" };
  char sep[5] = { "    " };
  char buf1[] = { "Please enter the name of the student's:" };
  char buf2[] = { "Please enter the student's id:" };
  char buf3[] = { "Please enter the student's DOB:" };
  char buf4[] = { "Please enter the student's gender:" };
  char buf5[] = { "Please enter the student's marital status:" };

  //O_CREAT requires a third argument the mode which specifies the access permission bits
  //S_IRWXU indicates that the user has read, write and execute permissions
  x = open( "/home/user/Desktop/Labsheets/Labsheet4/input.dat", O_RDWR | O_CREAT | O_TRUNC, S_IRWXU );
  //fd 0 is standard input and 1 is standard output
  //will read from standard input and place data in the buffer
  //read return number of bytes read
  int i;
  for( i = 0; i < 5; i++ )
  {
    write( 1, buf1, strlen(buf1) );
    read( 0, myArr[i].name, 20 );//read from standard input and place data in buffer
    write( 1, buf2, strlen(buf2) );;
    read( 0, myArr[i].id, 10 );
    write( 1, buf3, strlen(buf3) );
    read( 0, myArr[i].DOB, 9 );
    write( 1, buf4, strlen(buf4) );
    read( 0, myArr[i].gender, 1 );
	read( 0, dumb, 1 );
    write( 1, buf5, strlen(buf5) );
    read( 0, myArr[i].status, 1 );
	read( 0, dumb, 1 );
  }
  for(  i = 0; i < 5; i++ )
  {
    write( x, myArr[i].name, strlen(myArr[i].name) );
    write( x, sep, 4 );
    write( x, myArr[i].id, strlen(myArr[i].id) );
    write( x, sep, 4 );
    write( x, myArr[i].DOB, strlen(myArr[i].DOB) );
    write( x, sep, 4 );
    write( x, myArr[i].gender, strlen(myArr[i].gender) );
    write( x, sep, 4 );
    write( x, myArr[i].status, strlen(myArr[i].status) );
    write( x, newline, 4 );
  
  }
 
  return 0;
}

1) suggest you define macros STDIN and STDOU instead of hardcoding 0 and 1 in the read/write statements

#define STDOUT  1
#define STDIN   0

2) use sizeof operator to get the size of data

write( STDOUT, buf4, strlen(buf4) );
    read( STDIN, myArr[i].gender, sizeof(myArr[i].gender) );
    write( STDOUT, buf5, strlen(buf5) );
    read( STDIN, myArr[i].status, sizeof(myArr[i].status) );

[edit] And what they said above ^^^^ [/edit]

Edited 7 Years Ago by Ancient Dragon: n/a

1) suggest you define macros STDIN and STDOU instead of hardcoding 0 and 1 in the read/write statements

#define STDOUT  1
#define STDIN   0

2) use sizeof operator to get the size of data

write( STDOUT, buf4, strlen(buf4) );
    read( STDIN, myArr[i].gender, sizeof(myArr[i].gender) );
    write( STDOUT, buf5, strlen(buf5) );
    read( STDIN, myArr[i].status, sizeof(myArr[i].status) );

[edit] And what they said above ^^^^ [/edit]

Hi,
Please consider the following example code

char a, c;
scanf("%c", &c);
scanf("%c", &a);
//printf("[c:%c, a:%c]\n", c, a);

when we run it the second scanf() statement takes the '\n' that is entered while entering a character for the first scanf().
It may be because the input buffer is not reset after the first scanf().
But I tried doing an fflush(stdin) before the second scanf() and it still doesn't take the second input.
Can u put some light on this issue.

Thanks in advance

Edited 7 Years Ago by dkalita: n/a

Ok I understand the newline thingy since it is the same thing as with C++ when we use cin.get in C++ but then I am lost again do I need to cater for the null terminator lets say as in C++ I want to input a string of 20 characters in an array then I will have to use an array whose size is 21; that is I need to cater for the null terminator
C++:
char name[21]
cin.get( name, 21 );//cater for 20 characters plus null terminator
cin.get()//read newline left in input queue

What about read()?
with read() if i want to read a name of 20 characters do i need to write it like this read( 0, myArr.name, 21 ) - in this case catering only for the newline

or
read( myArr, name, 22 ) - in this case catering for both the newline and the null terminator

Edited 7 Years Ago by DARK_BYTE: n/a

This question has already been answered. Start a new discussion instead.