Home > OS >  How to I read from a file and output specific strings in c
How to I read from a file and output specific strings in c

Time:10-20

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.

  • Related