0

I'm programming in C and I need to know the number of lines of stdin. After a certain number of lines, I also need to scroll up one line...I used an ANSI escape code (033[1S), but I lose the content of the line scrolled and I don't wanna this.

EDIT: Simple code to explain the 2nd point

#include <stdio.h>

int main(void) { 
    printf("one\ntwo\nthree\n"); 
    fputs("\033[1S", stdout);
return 0; 
}
ubuntiano
  • 89
  • 1
  • 1
  • 6
  • Your ANSI escape code (`\x033` plus `[1S`) is used for controlling display on a terminal. – Benoit Jan 12 '11 at 18:51
  • My application run in a terminal. The problem is when I scroll with "033[1S"...I lose the content of the line scrolled (I see scrolling back) and I don't wanna lose the content. – ubuntiano Jan 12 '11 at 18:59
  • Your question is not clear. Try giving a simple example of what you are wanting and what is happening (using only a few lines to represent the terminal). Also talk about what is going on in your program at the various spots and what you mean by losing the content of the line. – nategoose Jan 12 '11 at 19:42
  • @nategoose: 1) how to count lines of stdin? 2) a simple example: #include int main(void) { printf("one\ntwo\nthree\n"); fputs("\033[1S", stdout); return 0; } see what happens at the scrolled line, it's cancelled and I don't wanna this...I wanna scroll, but without lose the content of line. – ubuntiano Jan 12 '11 at 19:56
  • @ubuntiano FYI you can edit your question and put the code there; it's very useful for those who wish to reproduce the behavior. (I tried, but noticed nothing special) – anatolyg Jan 12 '11 at 20:23
  • @anatolyg: Done. See again, after scrolling, if you come back, the line scrolled is cancelled. – ubuntiano Jan 12 '11 at 20:47

2 Answers2

1

this is a good reference for the ansi escape codes scroll down the page to the table of codes.

I believe you may need \033[1E in addition to "1S" to move down onto the new line. play around with the codes.

also I think you can get the lines/cols from the environment.

below code thanks to "Hko" from http://www.linuxquestions.org/questions/programming-9/linux-c-syscall-to-get-number-of-columns-of-current-terminal-250252/

#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdio.h>

int main()
{
    struct winsize ws; 

    ioctl(1, TIOCGWINSZ, &ws);
    printf("Columns: %d\tRows: %d\n", ws.ws_col, ws.ws_row);
    return 0;
}
Fire Crow
  • 7,499
  • 4
  • 36
  • 35
  • Thanks, but both solutions failed. With the 1st the result is the same, and the second return simply the number of columns and rows of the window (according to its size), not of stdin (written lines). – ubuntiano Jan 12 '11 at 20:53
  • oh so you need to track how many lines your program has output, just keep an in and ++ it every time your encounter a '\n' character as you read standard in. or if you mean lines youve written to stdout same thing just count them as you write '\n' characters. – Fire Crow Jan 12 '11 at 20:57
  • reading your question again I'm not clear on what you need. do you need to move the cursor up to a line that was previously printed to the screen by your program (stdout) or do you need to count the lines that are coming into your program stdin? – Fire Crow Jan 12 '11 at 21:03
  • It's a solution to count written lines, but to read them from stdin like we do from a stream (txt file opened for example)? I used fgets, but fail. And for the scrolling problem? EDIT: you edited your comment...I need both, count written lines and scrolling one line without lose the content of scrolled line. – ubuntiano Jan 12 '11 at 21:07
  • "I use fgets, but fail" what do you mean? you'll have to post more details than that I have no idea what success would be for you in this case. – Fire Crow Jan 13 '11 at 18:20
  • I used fgets as we do with an open stream (while(fgets(...) != NULL)) and counting number of '\n' to determine written lines (written lines == number of '\n'), but this approach fail. Any idea how to read the number of written lines from stdin? And for the scrolling question? – ubuntiano Jan 13 '11 at 18:43
  • "counting number of '\n' to determine written lines (written lines == number of '\n'), but this approach fail" this should not fail. I must be missing something. is the count of '\n' characters not matching the number of lines your receiving from stdin? – Fire Crow Jan 13 '11 at 19:34
  • The problem is that nothing happens...the program wait an action from user cause of fgets/fgetc. This approach work fine with next written line (after program launch), but I wanna count the previous written lines. Simple example: #include int main(void) { int c; int i = 1; printf("one\ntwo\nthree\n"); while((c=fgetc(stdin)) != NULL) { if (c=='\n') { printf("%d\n", i); i++; } } return 0; } I imagine that the cursor must be reposition at beginning of stdin, but rewind() or fseek() don't work on stdin and there is the problem of "pause" because of fgets/fgetc too. – ubuntiano Jan 13 '11 at 20:05
  • oh, I think you've misunderstood stdin, I'll post a second answer below. – Fire Crow Jan 13 '11 at 20:50
0

it looks like you're mistaken about what stdin is.

in your example int the comments:

#include <stdio.h> 
int main(void) { 
  int c; int i = 1; 
  printf("one\ntwo\nthree\n"); 
  //while((c=fgetc(stdin)) != NULL) { 
  // comparing it with null is not correct here
  // fgetc returns EOF when it encounters the end of the stream/file
  // which is why an int is returned instead of a char
  while((c=fgetc(stdin)) != EOF) { 
    if (c=='\n') { 
      printf("%d\n", i); i++; 
    } 
  } 
  return 0; 
}

calling the program from the command line should output this

$ prog
one
two
three

you must send it a stream or a pipe to give it information through stdin

$ cat myfile | prog
one
two
three
4 # or however many lines are in myfile

stdin is blank by default. if you type into it, nothing is sent until you hi enter

this is what I see from compiling hte above code:

1 ./eof_testing
one
two
three
jfklksdf #my typing here
1
fjklsdflksjdf #mytyping here
2
fjklsdflksdfjf # my typing here
3

----- adding example of stty system call ----

#define STDIN_FD 0
#define STDOUT_FD 1 
#define CHUNK_SIZE 8

#define QUIT_CHAR (char)4 /* C-D */
int main(){
  write(STDOUT_FD,"hi\n",3);
  char buff[CHUNK_SIZE];
  int r, i;
  system("stty -echo raw");
  while(r = read(STDIN_FD, &buff, CHUNK_SIZE)){
    for(i = 0; i < r; i++){
      if(buff[i] == QUIT_CHAR)
        goto exit;
    }
    write(STDOUT_FD, &buff, r);
  }
  exit:
    system("stty echo cooked");
    return 0;
}

now, however there is a whole new set of challenges to tackle, such as the key sends the '\r' character so instead of a newline it just returns to the start of the line. this is because now that the characters go directly to the program, lines are not terminated with the '\n' character which was happening in 'cooked' mode by the terminal.

http://starboard.firecrow.com/interface_dev/mle.git/editor/editor.c

Fire Crow
  • 7,499
  • 4
  • 36
  • 35
  • oh, we are agree! There isn't a way to do what I asked directly from stdin (only in C), but I must find a solution...copy stdin to another stream? it's possible? – ubuntiano Jan 13 '11 at 22:19
  • you could set things in raw mode system("stty raw -echo"); // code; system("stty cooked echo"); and that will let you see each character as its typed. or yes you could copy stdin to another stream, or array of chars, not sure what you could do with a copy that you can't do with the stdin stream though. – Fire Crow Jan 13 '11 at 22:43
  • Please, can you write simple example with system() for my case? – ubuntiano Jan 13 '11 at 23:12
  • Thanks a lot! I imagined new challenges that will not help me...I'm thinking to use a new approach: do a GUI that can help me, but I don't wanna dependencies, so I'm thinking to use xlib. Do you know if it's possible substitute the work of "033[1S" (or others ANSI escape codes) with its function? – ubuntiano Jan 14 '11 at 18:00
  • not familiar with xlib, ncurses or curses is probably your best gui-ish/terminal thing that's light weight – Fire Crow Jan 14 '11 at 19:41
  • Using ncurses is good solution too...add a dependency (using ncurses) and all can use it or no dependences (using xlib), but only X system users can use it?! :D What's fflush() implementation with ncurses? – ubuntiano Jan 15 '11 at 22:05