I'm writing a program that will read from /etc/passwd and output the username and shell.
For example, here is the first line of the /etc/passwd file:
root:x:0:0:root:/root:/bin/bash
I need to only output the user and the shell. In this instance it would print:
root:/bin/bash
The values are seperated by : so I just need to print the string before the first : and the string after the 6th :
Here is the code I have so far:
#include <unistd.h>
#include <fcntl.h>
//printf prototype
int printf(const char *text, ...);
void customized_print(char* buff,char* outbuff);
int main(void)
{
int fd;
int buff_size = 1;
char buff[512];
char outbuff[512];
int size;
fd = open("/etc/passwd",O_RDONLY);
if (fd < 0)
{
printf("Error opening file \n");
return -1;
}
while ((size = read(fd,buff,1))>0)
{
buff[1] = '\0';
customized_print("%s",outbuff);
}
}
void customized_print(char* buff,char* outbuff)
{
int i = 0, j = 0, count = 0;
while (i<512)
{
if((outbuff[j ]=buff[i ] == ':'))
break;
}
while(i<512 && count < 5)
{
if(buff[i ] == ':')
count ;
}
while (i < 512)
{
if( (outbuff[j ]=buff[i ] == '\0'))
break;
}
printf("%s\n",outbuff);
}
Im having some trouble utilizing the custimized print function to work when reading from a file
(Im creating prototypes for printf because one of the requirments was to wite the program without including stdio.h and stdlib.h)
CodePudding user response:
Don't try to manipulate each-and-every character in "hand-rolled" code. (/etc/passwd is a rare instance of reliable external source data.)
#include <io.h> // Working with windows. Adapt as needed.
#include <fcntl.h>
int main() {
int fd = open( "/etc/passwd", O_RDONLY ); // has been tested
if( fd < 0 ) {
write( 2, "Error opening file \n", 20 );
return 1;
}
#define FLDS 0x41 // bit field flags to control output
uint16_t flg = FLDS;
char c;
while( read( fd, &c, 1 ) == 1 ) { // low level, one char at a time.
if( flg & 0x1 )
write( 1, &c, 1 ); // output only when LSB of flag gates it thru
if( c == ':' )
flg >>= 1; // adjust flags on field separators
if( c == '\n' )
flg = FLDS; // reset flags on line separators
}
close( fd );
return 0;
}
Note: This takes advantage of the trailing '\n' of the final field being printed. To swallow that, then manually insert a LF is left as an exercise for the reader.
For input
root:x:0:0:root:/root:/bin/bash
foo:x:0:0:foo:/foo:/bin/sh
root:/bin/bash
foo:/bin/sh
CodePudding user response:
You can read binary.
FILE * fp = fopen(file_name, 'rb'); //rb = read binary
int a;
//Read the next int (4 byte, and char=1byte)
fread(&a, sizeof(int), 1, fp);
//it will juste copy all bits into the `a` register from the file.
Juste for info. It's not a solution, but looking an other way can help you.