Hi i don't know how to simulate my own Cat function in C, i know how it works when no arguments are set and i already get it, but my problem is when i tried to open a file and then print itself...
my code until now:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
int main(int argc, char* argv[])
{
char *a1 = (char*) malloc (sizeof(char));
int sz, fd,cont=0, cont1=0;
char *b1 = (char*) malloc (sizeof(char));
//char *a2 = (char*) malloc (sizeof(char));
char * a2;
char *b2 = (char*) malloc (sizeof(char));
// NO PARAMETERS
while (argc == 1){
sz=read(0, a1, 1);
b1[cont]=a1[0];
if(b1[cont]=='\n'){
write(1,b1,cont);
write(1,"\n",1);
b1=NULL;
}
cont=cont+1;
b1=(char*) realloc(b1, sizeof(char)*cont);
}
// 1 PARAMETER (FILE) /*Here is the problem*/
if (argc > 1){
fd=open(argv[1],O_RDONLY);
a2=fgetc(fd);
while (a2 != EOF){
b2[cont1]=a2;
cont1=cont1+1;
b2=(char*) realloc (b2, sizeof(char)*cont1+1);
a2=fgetc(fd);
}
write(1,b2,cont);
b2=NULL;
close(fd);
}
return 0;
}
What am i supposed to do ?
If you are using open()
and close()
, you cannot use fgetc()
. You need to use fopen()
and fclose()
to be able to use fgetc()
.
Either way, you need a function which can be called with either the standard input (spelled 0
or stdin
) or with the file that was opened (fd
or fp
are conventional names for 'file descriptor' and 'file pointer'). You can specify the output stream too. Hence, for example, the interfaces:
int cat_fd(int ifd, int ofd);
int cat_fp(FILE *ifp, FILE *ofp);
Your main program then calls your chosen function with the standard input and standard output or with the opened file and standard output.
Additionally, you have:
char *a1 = (char*) malloc (sizeof(char));
Ignoring the cast, this is an expensive way of writing:
char a1[1];
Your loops are reading a single character at a time. This is OK with the file streams from <stdio.h>
, but is bad for performance if you're using file descriptors. You should be reading block of, say, 4096 characters at a time.
int cat_fd(int ifd, int ofd)
{
char buffer[4096];
ssize_t nbytes;
while ((nbytes = read(ifd, buffer, sizeof(buffer))) > 0)
{
if (write(ofd, buffer, nbytes) != nbytes)
return -1;
}
return (nbytes < 0) ? -1 : 0;
}
You don't need the dynamic memory allocation; it is only confusing you and wasting time in the program. The code in the main()
function then looks more like:
if (argc == 1)
{
if (cat_fd(0, 1) != 0)
fprintf(stderr, "failed to copy standard input\n");
}
else
{
for (int i = 1; i < argc; i++)
{
int fd = open(argv[i], O_RDONLY);
if (fd < 0)
fprintf(stderr, "failed to open %s for reading\n", argv[i]);
else
{
if (cat_fd(fd, 1) != 0)
fprintf(stderr, "failed to copy %d to standard output\n", argv[i]);
close(fd);
}
}
}
Rewriting to use cat_fp()
is an exercise for the reader. You might find Tried and true simple file copying code in C relevant.