I'm trying to emulate a tail
command in C but I have a problem.
I need to read some lines from keyboard (STDIN) (I don't care how many lines). This read will be interrupted when Ctrl+d is pressed. I have done this function but it doesn't work.
int tail(int N)
{
int i, j, c;
char ** lines;
/* Char matrix dynamic declaration */
lines=NULL; // Char matrix declaration
lines=malloc(N*sizeof(char *));
for (i=0; i<N; i++){
lines[i]=malloc(80 * sizeof(char));
}
i=0;
while (true){ // I tried this loop, but doesn't work
/* This works. Lanes reading from the user's keyboard */
if(i>=N){
for(j=0; j<=N; j++){
if (j<(N-1))
lines[j]=lines[j+1];
}
scanf(" %[^\n]", lines[N-1]);
}else{
scanf(" %[^\n]", lines[i]);
}
i++;
/* ------------------------------------ */
c=getchar(); // This doesn't work
if(c==EOF)
goto end;
}
end:
for (i=0; i<N; i++){
printf("%s\n", lines[i]); // Showing those lanes
free(lines[i]); // Free memory
}
free(lines);
lines = NULL;
return 0;
}
My problem is about read user's keyboard lines and read ctrl+d at the same time. When I launch the function, it let me write some lines, but it doesn't detect when I press Ctrl+D. How can I do this?
I have tried a new method to capture Ctrl+d and now my program ends, but I have some problems. Here is the new code:
int tail(int N)
{
int i, j, k, c;
char ** lines;
lines=NULL;
lines=malloc(N*sizeof(char *));
for (i=0; i<N; i++){
lines[i]=malloc(MAXLON * sizeof(char));
}
i=0;
while (true){
/* Read lines from keyboard. */
if(i<N)
scanf(" %[^\n]", lines[i]);
else{
for(j=0; j<N-1; j++){
for(k=0; k<MAXLON; k++){
lines[j][k]=lines[j+1][k];
}
}
scanf(" %[^\n]", lines[N-1]);
}
/* ------------------------------------ */
if((c=getchar())==EOF) break;
else i++;
}
for (i=0; i<N; i++){
printf("%s\n", lines[i]);
free(lines[i]);
}
free(lines);
lines= NULL;
return 0;
}
Right now, my program captures N lines from keyboard until I press 2 times Ctrl+d, but my problem now is: If I write 5 lines which are (with tail(3) for example, which shows the last 3 lines):
Line 1
Line 2
Line 3
Line 4
Line 5
AND HERE I PRESS 2 TIMES CTRL+D
The function shows:
Line 4
Line 5
Line 5
Whats wrong? The function must show:
Line 3
Line 4
Line 5
Thank you so much!
Please see the following code as a working example:
#include <stdio.h>
int main(int argc, char* argvp[])
{
char buf[1024];
while(gets(buf))
{
printf("Read: %s\n", buf);
}
if (ferror(stdin))
puts("I/O error when reading");
else if (feof(stdin))
puts("End of file reached successfully");
}
Please note that
buf
should not be hard-codedgets
is deprecated and you should use something else like fgets
gets
in the middle of a line. It has to be the first line symbol. It is so on my RHEL 7.1 but might be different on your systemstdin
should be replaced with your real input file descriptor