Ncurses: temporarily leaving curses mode not working

D

dachteruit

Hi all,

First of all I'm a newbie in C programming and I was playing around
with ncurses.
I've followed the instructions as described in
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/misc.html#TEMPLEAVE to
leave curses mode temporarily. So I wrote the following:

#include <stdio.h>
#include <ncurses.h>
#include <string.h>

int main(){
int i=0, j=2560;
char last, result[j];
initscr();
cbreak();
refresh();
do {
last = getch();
def_prog_mode();
endwin();

strcat(last, result);
printf("Last one is: %c\n", last); //doesn't work
printw("The very last one is: %c\n", last); //printw does still
work!!!

reset_prog_mode();
refresh();
}while(last != 's');

for(j=0;j<2560;j++) printw("%c", result[j]);
refresh();
getch();

endwin();

return 0;
}

Can anyone explain me why printw works and printf don't when I'm
temporarily out of curses mode?
In addition you may explain too why the for-loop returns a scrambled
output, but that's not yet my main problem.

Thanks,

Nico
 
K

Keith Thompson

dachteruit said:
First of all I'm a newbie in C programming and I was playing around
with ncurses.
I've followed the instructions as described in
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/misc.html#TEMPLEAVE to
leave curses mode temporarily. So I wrote the following:

ncurses isn't part of the C language/library standard.
comp.unix.programmer is probably a better place to ask about it.

I'll comment on some purely C-related aspects of your code.
#include <stdio.h>
#include <ncurses.h>
#include <string.h>

int main(){

"int main(void)" is better. ("int main()" would be preferred in C++.)
int i=0, j=2560;
char last, result[j];


This declares last and results as variable-length arrays (VLAs), which
means that the length of the array can be determined at run time. Since
the values you're using are always going to be the same, there's not
much point in using VLAs rather than just plain fixed-length arrays.

Note that the length of a VLA is fixed at run time when the object is
created; changing the value of i won't change the size of last.

For "result", for example, you could have written:

#define RESULT_LENGTH 2560;
int j = RESULT_LENGTH;
char result[RESULT_LENGTH];

But since you assign a new value to j (in the for loop) before ever
reading it, there's no point in initializing it here.

As for last, since i is 0, you're trying to create a zero-length
array. C doesn't support this, and your program's behavior is
undefined. (The most likely result is that attempting to access
any elements of last will scribble on other memory.)

Hmm. You never change the value of i, so it's always 0. last would
be a char object if it existed. Probably you just wanted to declare
last as a char.

Correction: since you're it to store the value returned by getch(),
it should be an int (consult your documentation, you'll find that
getch(), at least the one provided by ncurses, returns an int).
initscr();
cbreak();
refresh();
do {
last = getch();
def_prog_mode();
endwin();

strcat(last, result);
printf("Last one is: %c\n", last); //doesn't work
printw("The very last one is: %c\n", last); //printw does still
work!!!

reset_prog_mode();
refresh();
}while(last != 's');

for(j=0;j<2560;j++) printw("%c", result[j]);


And since you're using C99-specific features anyway (VLAs), you might
as well declare j in the loop:

for (int j = 0; j < RESULT_LENGTH; j ++) ...

Note that I'm using a named constant, which makes maintenance of
your program easier; if you want to make the result array bigger
or smaller, you only have to change the number in one place.
refresh();
getch();

endwin();

return 0;
}
[...]
 
I

Ian Collins

dachteruit said:
First of all I'm a newbie in C programming and I was playing around
with ncurses.
I've followed the instructions as described in
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/misc.html#TEMPLEAVE to
leave curses mode temporarily. So I wrote the following:
#include<stdio.h>
#include<ncurses.h>
#include<string.h>

int main(){

"int main(void)" is better. ("int main()" would be preferred in C++.)
int i=0, j=2560;
char last, result[j];


This declares last and results as variable-length arrays (VLAs), which
means that the length of the array can be determined at run time. Since
the values you're using are always going to be the same, there's not
much point in using VLAs rather than just plain fixed-length arrays.


Also note that a VLA with a length of zero isn't going to do you much
good and is probably the cause of many of your problems!
 
A

Alan Curry

int main(){
int i=0, j=2560;
char last, result[j]; [...]
strcat(last, result); [...]
for(j=0;j<2560;j++) printw("%c", result[j]);


Besides the trouble with the zero-length last[] array, you have also used the
contents of the result[] array without ever putting anything in it. Did you
get the order of arguments of strcat() backwards? It's hard to figure out
what you thought you were doing, with so many mistakes everywhere.

It'll be impossible to determine what's going on with your curses code until
you clean up this wacky string-handling code.

I seem to recall using endwin() and refresh() to leave and re-enter curses.
def_prog_mode() and reset_prog_mode() are probably not necessary.
 
K

Keith Thompson

Ian Collins said:
dachteruit said:
First of all I'm a newbie in C programming and I was playing around
with ncurses.
I've followed the instructions as described in
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/misc.html#TEMPLEAVE to
leave curses mode temporarily. So I wrote the following:
#include<stdio.h>
#include<ncurses.h>
#include<string.h>

int main(){

"int main(void)" is better. ("int main()" would be preferred in C++.)
int i=0, j=2560;
char last, result[j];


This declares last and results as variable-length arrays (VLAs), which
means that the length of the array can be determined at run time. Since
the values you're using are always going to be the same, there's not
much point in using VLAs rather than just plain fixed-length arrays.


Also note that a VLA with a length of zero isn't going to do you much
good and is probably the cause of many of your problems!


Yes, I pointed that out in the part you snipped.

The behavior is undefined; see C99 6.7.5.2p5.
 
I

Ian Collins

Ian Collins said:
First of all I'm a newbie in C programming and I was playing around
with ncurses.
I've followed the instructions as described in
http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/misc.html#TEMPLEAVE to
leave curses mode temporarily. So I wrote the following:
#include<stdio.h>
#include<ncurses.h>
#include<string.h>

int main(){

"int main(void)" is better. ("int main()" would be preferred in C++.)

int i=0, j=2560;
char last, result[j];

This declares last and results as variable-length arrays (VLAs), which
means that the length of the array can be determined at run time. Since
the values you're using are always going to be the same, there's not
much point in using VLAs rather than just plain fixed-length arrays.


Also note that a VLA with a length of zero isn't going to do you much
good and is probably the cause of many of your problems!


Yes, I pointed that out in the part you snipped.

The behavior is undefined; see C99 6.7.5.2p5.


Ah sorry, I didn't spot that bit.
 
D

dachteruit

dachteruit   said:
int main(){
   int i=0, j=2560;
   char last, result[j]; [...]
           strcat(last, result); [...]
   for(j=0;j<2560;j++) printw("%c", result[j]);


Besides the trouble with the zero-length last[] array, you have also used the
contents of the result[] array without ever putting anything in it. Did you
get the order of arguments of strcat() backwards? It's hard to figure out
what you thought you were doing, with so many mistakes everywhere.

It'll be impossible to determine what's going on with your curses code until
you clean up this wacky string-handling code.

I seem to recall using endwin() and refresh() to leave and re-enter curses.
def_prog_mode() and reset_prog_mode() are probably not necessary.


Ok, now I know what I can do tomorrow.
It seems like I still have a lot to learn.

Nico
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,954
Messages
2,570,116
Members
46,704
Latest member
BernadineF

Latest Threads

Top