Hello, I am developng a screen for a state to enter special rates to augment its unemployment trust fund. I have the screen coded, and it compiles cleanly, but when I try to run it, the screen does not come up. There is no error message and no file I can have debug messages appear, so I am not sure what the problem is. The screen is written in C, using the curses library, and is compiled with the gcc compiler. I have added all the debug options I can to the gcc call line, but they just debug during compilation, not runtime. The screen reads starting at line165 from a file that has other data( all that reads cleanly), and I have verified the read/write logic in another program. The code I have is:

#include <stdio.h>
#include <curses.h>
#include <term.h>
#include <stdlib.h>
/*globals*/
#define KDN 258
#define KUP 259
#define KL  260
#define KR  261
#define CR 13
#define SP 32
#define MORE TRUE
#define GETDAT TRUE
/*GLOBALS for window*/
WINDOW *win;
int ijlim[4] = {0,9, 0,4};
int xrych[2] = {5,4};
int xycur[2] = {10,6};
/* int xcolh[4]; */
int i,j,x,y,key,imv,jmv,ijprv,xt,nqtrs=5,rpldgt,yfmt=21,xtab=10;
int yskip=0,nskip=0,ij=-1;
double tbl[9][9]; /*9 lines x 9 col*/
double val,vtmp;
char vstr[20];
static float vmax[17];
static float vmin[17];
char *shofmt[17];
char *edfmt[17];
/* edit format includes an extra space for decimal values */
/* end GLOBALS*/
#include "mvc6.cfn"
#include "wvg.cfn"
#include "nerrmsg.cfn"
#include "rplnum2.cfn"
#include "rpldgt.cfn"
#include "prtscr.cfn"
#include "center.cfn"
#include "mpick2.cfn"
main()
{
  FILE *upd;
  FILE *mdl = fopen("model.d","r"); /* R for Reserve, B for Benefit */
  char model, st;
  char ppcard[87];
  char ktti[17];
  char *riptr[12], *ptr, *fmt;
  char ristr[20];
  char ch;
  char *range[] = {"1-9","10-18","19-27","28-36","37-45","46-54","55-63","64-72","73-81"};
  char *digits[] = {" 1"," 2"," 3"," 4"," 5"," 6"," 7"," 8"," 9"};
  double *dptr1, *dptr;
  int imove[17];
  static char *disp[] = {"MORE EDITS","   SAVE   ","START OVER","  CANCEL  "};
  static char *help[] = {"Change more items", "Update the data file",              "Nothing saved; recall original data", "Quit without saving"};
  char *dash[] = {"-----","--------"};
  char *qtr[] = {"1stQ","2ndQ","3rdQ","4thQ"};
  char *xfmt[] = {"XX.XX%","XX.XX%"};
  char *baseYearHead = {"Surcharge Applied Base Year (YES=1, NO=0)?"};
  char *percentageHead = {"Minimum Apply Percentage      Maximum Apply Percentage"};
  int ncard,icd,nvar,nxtcd,k,n,lnbeg,baseyr,lastyr,rtlf,bad,flag,chkbk,neg,xch0,xch1,nread;
  int ilast,jlast,ylast,xlast,next,knt,isched,knri,nrates,nrow,jmax,xlm,kfpy1,kcd,len,iyr,nchrs,addch,imax;
  int hil=1,baseYearSurcharge;
  int iLine, iField, iOffset, iNewOffset;
  double xprap,xnrap,lorap,hirap,solvpctchkinitial,solvpctchkmaximum;
  /* locators for SPECIFIC VARIABLES option (-1, 0 if menu entry) */
  int iscrn=-1, idrow=0;
  FILE *in = fopen("temp.d","r");
  fscanf(in,"%d%d",&iscrn,&idrow);
  fclose(in);
  #include "wset.cd"
  wattrset(win,A_NORMAL);
  wattron(win,A_BOLD);
  center("SOLVENCY SURCHARGE RATES",0);
  wattroff(win,A_BOLD);
  /* mvwaddstr(win,3,5,"Year"); */
  wrefresh(win);
  if((upd = fopen("dmtemp.d","r+")) == NULL)
  {
     mvwprintw(win,10,0,"**ERROR** file dmtemp.d MISSING or WRITE PROTECTED");
     wrefresh(win);
     sleep(1);
     endwin();
     exit(1);
  }
  /* get 1st comp yr */
  fscanf(mdl,"%c",&model);
  fclose(mdl);
  if(model=='R') ncard=59;
  lnbeg=81*(ncard-1)+1;
  fseek(upd,lnbeg,0);
  fscanf(upd,"%d15c%*12c%d",&knt,&ktti[1],&knri);
  knri++;
  nqtrs=(knri+8)/9;
  jmax=nqtrs-1;
  sprintf(range[jmax]+3,"%2d",knri);
  imax=knt-1;
  for(i=1;i<=knt;i++)
    imove[i]=1;
  imove[0]=imove[knt+1]=-imax;
  wrefresh(win);
  imax=(knri-1)%9;
  while(TRUE)
  {
    while(GETDAT)
    {
      /* i=1; y=4; x=xlm; j=0; */
      /* GET DATA from file */
      ncard=165;
      lnbeg=81*(ncard-1);
      fseek(upd,lnbeg,0);
      fgets(ppcard, 82, upd);
      sscanf(ppcard, "%d", &baseYearSurcharge);
      mvwaddstr(win,43,3,baseYearHead);
      mvwprintw(win,2,10,"%d",baseYearSurcharge);
      fgets(ppcard, 82, upd);
      sscanf(ppcard, "%lf  %lf", &solvpctchkinitial, &solvpctchkmaximum);
      mvwaddstr(win,55,3,percentageHead);
      mvwprintw(win,6,15,"%lf                      %lf",solvpctchkinitial, solvpctchkmaximum);
      mvwaddstr(win,7,3,"Rate #");
      wrefresh(win);
      /* Read Solvency Surcharges from cards 167 through 175 */
      /* Always read 9 lines, with 9 fields each, but only the first (knri) are valid. */
      for (iLine = 0, x = 9, j = 0; iLine < 9; ++iLine, x += 9, j++)
      {
        mvwaddstr(win,9,x,range[j]);
        ilast=9;
        if(iLine==jmax) ilast=imax;
        /* Read the next line into ppcard, an array at least 81 characters in size. */
        fgets(ppcard, 82, upd);
        iOffset = 0;
        for (iField = 0, y = 9, i = 0; iField < 9; ++iField, y++, i++)
        {
          if ((iLine * 9) + iField > knri)
          {
              /* If we are past the last significant rate, stop processing, but keep reading. */ 
              break;
          }
          else
          {
            if(iLine==0) {sprintf(digits[iField],"%2d",i+1); mvwaddstr(win,y,5,digits[iField]);}
            if (sscanf(ppcard + iOffset, "%lf%n", &tbl[iField][iLine], &iNewOffset) < 1)
            {
              /* stop reading this line and try the next. */
              break;
            }
            else
            {
              mvwprintw(win,y,x,"%lf",tbl[iField][iLine]);
              /* Add on the length of the last field so that we start reading the next number after that */ 
              iOffset += iNewOffset;
            }
          }
        }
      } /* end READ solvency surcharges */
      wrefresh(win);
      while(MORE)
      {
        wattroff(win,A_STANDOUT);
        mvwprintw(win,yfmt,25,"Always HIT RETURN to complete (or correct) an entry");
        mvwprintw(win,22,0,"To replace a VALUE, just type the new value");
        mvwprintw(win,23,0,"To replace single DIGIT(s), use the SPACE BAR to move cursor");
        mvcurs(baseYearHead,1,baseYearHead,-1,1,1,1);
        wmove(win,y,x-1);
        key=KDN; i=j=0; y=9; x=9; xrych[1]=9; ijprv=-1; 
        while(TRUE)
        {
          noecho();
          key=wgetch(win);
          if(key==CR) break;
          mvcurs(percentageHead,1,percentageHead,-1,1,1,1);
          wmove(win,y,x-1);
          if(key>=KDN)
          {
            /*put cursor over next group until non-arrow key hit#*/
            imv=jmv=0;
            ijlim[3]=jmax;
            if(i>imax) ijlim[3]--;
            ijlim[1]=9;
            if(j==jmax) ijlim[1]=imax;
            mvcurs(digits,1,range,9,1,1,1);
            /* reprint new column range */
            for(k=0; jmv && k<9; k++)
            {
              if(j>0)
                ch=j + '0';
              else
                ch=' ';
              *digits[k]=ch;
              if(k==8)
                *digits[8]=j + '1';
              if(k==i)
                wattron(win,A_STANDOUT);
              else
                wattroff(win,A_STANDOUT);
              if(j<nqtrs-1 || k<=imax)
                mvwaddstr(win,k+8,5,digits[k]);
              else
                mvwaddstr(win,k+8,5,"  ");
              wmove(win,y,x-1);
            }
          }
          else if(key>='-' && key<='9')
          {
            if(i>imax) nqtrs--;
            repl_num(); /* uses std scan to get new # */
            if(i>imax) nqtrs++;
          }
          else if(key==SP)
          {
            repl_dgt(); /* uses space to flag typeover, move cursor to digit(s) */
          }
        } /* end edit loop (while TRUE)*/
        wattroff(win,A_STANDOUT);
        ilast=i; jlast=j;
        ylast=y; xlast=x;
        /* add check for rates in sequence (RR, OK decr, BR incr) */
        wattron(win,A_BOLD);
        vtmp=tbl[0][0]; flag=chkbk=FALSE;
        for(j=0,k=0; j<9; j++)
        {
          for(i=0; i<9 && k<knri; i++,k++)
          {
            bad=FALSE;
            if(model=='R' && tbl[i][j]>vtmp)
            {
              bad=TRUE;
            }
            else if(model=='B' && st=='W' && tbl[i][j]>vtmp) /* OK */
            {
              bad=TRUE;
            }
            else if(model=='B' && st!='W' && tbl[i][j]<vtmp) /* others */
            {
              bad=chkbk=TRUE;
            }
            if(bad)
            {
              flag=TRUE;
              mvwaddstr(win,i+8,j*10+15,"<--");
            }
            vtmp=tbl[i][j];
          }
        }
        if(flag)
        {
          mvwaddstr(win,20,10,"WARNING:  Rate out of sequence (<--)");
        }
        else
        {
          wmove(win,20,10);
          wclrtoeol(win);
        }
        if(chkbk) wprintw(win,":  Check previous value");
        wattroff(win,A_BOLD);
        wrefresh(win);
        /* get next-step choice*/
        y=xrych[1]=21; ijlim[3]=3; ijprv=-1;
        x=20;
        wmove(win,y,0);
        wclrtobot(win);
        wattron(win,A_STANDOUT);
        mvwprintw(win,21,x,disp[0]);
        mvwprintw(win,23,0,help[0]);
        wattroff(win,A_STANDOUT);
        mvwaddstr(win,21,0,"Next step:");
        for(j=1,x=35; j<4; j++,x+=15)
        {
          mvwprintw(win,y,x,disp[j]);
        }
        x=20; j=0;
        wmove(win,21,x);
        while(TRUE)
        {
          key=wgetch(win);
          if(key==CR) break;
          mvcurs(disp,-1,disp,15,1,0,1);
          wmove(win,23,0);
          wclrtoeol(win);
          mvwprintw(win,23,0,help[j]);
          wmove(win,y,x);
          wrefresh(win);
        }
        wattroff(win,A_STANDOUT);
        next=j;
        if(next==1)
        {
          wrefresh(win);
          ncard=165;
          lnbeg=81*(ncard-1);
          fseek(upd,lnbeg,0);
          fprintf(upd,"%d",baseYearSurcharge);
          fprintf(upd,"%lf    %lf",solvpctchkinitial, solvpctchkmaximum);
          dptr1=&tbl[0][0];
          for (iLine = 0; iLine < 9; ++iLine)
          {
            iOffset = 0;
            for (iField = 0; iField < 9; ++iField)
            {
              if ((iLine * 9) + iField > knri)
              {
                break;
              }
              else
              {
                fprintf(upd,"%lf",tbl[iField][iLine]);
                iOffset += iNewOffset;
              }
            }
          }
          sleep(1);
          wmove(win,7,0);
          wclrtobot(win);
          echo();
          wscanw(win,"%c",&ch);
          if(ch=='y') next=2;
          else fclose(upd);
        } /* end file SAVE */
        wmove(win,y,0);
        wclrtobot(win);
        if(next != 0) break; /* 0 = MORE EDITS */
        /* reset to last-edit state */
        i=ilast; j=jlast;
        y=ylast; x=xlast;
      } /*end MORE*/
      if(next != 2) break; /* 2 = START OVER */
      wattrset(win,A_NORMAL);
      /* mvwaddch(win,4,xlm+3*isched,ktti[isched+1]); */
      wmove(win,7,0);
      wclrtobot(win);
    } /*end GETDAT*/
    endwin();
  } /* end while TRUE */
} /*end prog*/

The input I am trying to read starting at line 165 is as follows:

P7
1
0.005 0.007
3.150 3.050 2.900 2.850 2.700 2.600 2.550 2.450 2.300
2.150 2.050 1.900 1.800 1.650 1.500 1.400 1.250 1.150
1.050 1.000 0.900 0.850 0.750 0.700 0.650 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000

If the screen worked, the output I expect to see would look like this:

                          SOLVENCY SURCHARGE RATES

              Surcharge Applied Base Year (YES=1, NO=0)  1

              Minimum Apply Percentage 0.005     Maximum Apply Percentage 0.007           

Rate # 1-10 11-20 21-25

  1    3.15      2.05      0.90
  2    3.05      1.90      0.85
  3    2.90      1.80      0.75
  4    2.85      1.65      0.70
  5    2.70      1.50      0.65
  6    2.60      1.40
  7    2.55      1.25
  8    2.45      1.15
  9    2.30      1.05
 10    2.15      1.00


                     Always HIT RETURN to complete (or correct) an entry

To replace a VALUE, just type the new value
To replace single DIGIT(s), use the SPACE BAR to move cursor

Any help I can get with this problem is greatly appreciated.

Recommended Answers

All 7 Replies

Line 15, your WINDOW pointer is never allocated, yet you are trying to manipulate it. I would expect that your application would dump core. It would if you initialized it to a null pointer when you declared it.

Your reply makes sinse. However, the screens I work with all have the same logic, and they work, without intializing the win variable. The code I gave you was actually based off of one those screens. I am not sure of how they work without intializing, but I am fairly new to working with the curses library and am on a learning curve. Below is an example of a working screen in the system I work on. I apologize for the horrible alignment of the code, but I inherited this code and and do not have time to align all these screens, with the other work I have to get done.

#include <stdio.h>
#include <curses.h>
#include <term.h>
#include <stdlib.h>
/*globals*/
#define KDN 258
#define KUP 259
#define KL  260
#define KR  261
#define CR 13
#define SP 32
#define MORE TRUE
#define GETDAT TRUE
/*GLOBALS for window*/
WINDOW *win;
int ijlim[4] = {0,9, 0,0}; /* IMPORTANT ! Defines i,j ranges for tbl[i][j] */
                           /* In this case, it indicates that there will be
                              10 lines and 1 column.*/
int xrych[2] = {25,3};
int xyold[2], xycur[2]={10,6};
int i,j,x,y,key,imv,jmv,ijprv,xt,nqtrs=1,rpldgt,yfmt=20,xtab=13;
int ij=-1;
int yskip=0,nskip=0;
double tbl[2][2]; /*2 vars x 2 col*/
                   /* Defines the MAXIMUM screen values. */
                   /* In this case, 10 x 1 are the ACTUAL values. */
double val,vtmp;
char vstr[20];
static float vmax[15];
static float vmin[15];
char *shofmt[15];
char *edfmt[15];

/* end GLOBALS*/
#include "mvc6.cfn"
#include "wvg.cfn"
#include "nerrmsg.cfn"
#include "rplnum.cfn"
#include "prtscr.cfn"
#include "rpldgt.cfn"
#include "center.cfn"
#include "fixcrd.cfn"
main()
{
FILE *upd;
char ppcard[82];
char *sched[] = {"Amount"};
char *riptr[12], *ptr;
char ristr[72],ch;
static char *disp[] = {"MORE EDITS",
                       "   SAVE   ",
                       "START OVER",
                       "  CANCEL  "};
static char *help[] = {"Change more items",
                       "Update the data file",
                       "Nothing saved; Recall original data",
                       "Quit without saving"};
char *qtr[] = {"1stQ/yy","2ndQ/yy","3rdQ/yy","4thQ/yy"};
int ncard,icd,nvar,nxtcd,k,n,lnbeg,neg;
int ilast,jlast,ylast,xlast,next,kfpy1,kcd,len,iyr;
/* locators for SPECIFIC VARIABLES option (-1, 0 if menu entry) */
int iscrn, idrow;
char model,st;
FILE *in = fopen("model.d","r");
fscanf(in,"%c%c",&model,&st);
fclose(in);
#include "wset.cd" /* std scr setup */
wattrset(win,A_NORMAL);
wattron(win,A_BOLD);
center("Statutory Tax Rate Reduction",0);
wattroff(win,A_BOLD);
wrefresh(win);
if((upd = fopen("dmtemp.d","r+")) == NULL)
  {
  mvwprintw(win,10,0,"**ERROR** file dmtemp.d MISSING or WRITE PROTECTED");
  wrefresh(win);
  sleep(1);
  endwin();
  exit(1);
  }
/* get 1st comp yr from card <34,24,14> cols 2-3 */
if(model=='R') ncard=34;
else if(model=='B') ncard=24;
else ncard=14; /* ID or MI */

/****** FILL POSITIONS *******/
        lnbeg=81*(ncard-1)+1;
        fseek(upd,lnbeg,0);
/*****************************/

fscanf(upd,"%2d",&kfpy1);
kfpy1+=1901+100*(kfpy1<80);
fseek(upd,-2,1); /* GO BACK 2 SPACES */

/* find the P8 card, fix for neg #s */
do{
  fgets(ppcard,82,upd);
  ncard++;
  /* PJ 6-12-02 Add the following segment to check dmtemp.d */
  if(ncard>70){
        wattron(win,A_BOLD);
        mvwprintw(win,10,0,"**ERROR**  Incorrect file dmtemp.d. ");
        wrefresh(win);
        sleep(3);
        mvwprintw(win,10,0,"\n\n  Please check file dmtemp.d for validity. PROGRAM QUITS.");
        wrefresh(win);
        wattroff(win,A_BOLD);
        endwin();
        exit(2);
  }
}while(strncmp(ppcard,"P8",2) );

fixcrd(ppcard,70);
while(GETDAT) /* START OVER LOOP */
{
wattroff(win,A_STANDOUT);
mvwaddstr(win,5,25,"Year");
mvwaddstr(win,5,50,sched[0]);
  /* MAKE ptr array for proj yr row hdgs, store fmts & limits */
  for(i=0,y=7,n=2,iyr=kfpy1,ptr=ristr; i<2; i++,y++,n+=7,iyr++,ptr+=5)
    {
    sscanf(&ppcard[n],"%7lf",&tbl[i][0]); /* 1 lead blank */
    //mvwprintw(win,y,50,"%-.1lf",tbl[i][0]);
    mvwprintw(win,y,50,"%-.5.2f",tbl[i][0]);  // @@@
    sprintf(ptr,"%d",iyr);
    mvwaddstr(win,y,25,ptr);
    riptr[i]=ptr;
    edfmt[i]="%7lf";
    shofmt[i]="%-.2lf";
    vmin[i]=-1000.0;
    vmax[i]=10000.0;
    }
wrefresh(win);
key=KDN; i=j=0; y=7; x=50; ijlim[1]=9; xrych[0]=25; xrych[1]=5; ijprv=-1;
while(MORE)  /* EDIT LOOP */
{
wattron(win,A_STANDOUT);
mvwaddstr(win,yfmt,0,"Format: Millions");
wattroff(win,A_STANDOUT);
mvwaddstr(win,yfmt,25,"Always HIT RETURN to complete (or correct) an entry");
mvwaddstr(win,22,0,"To replace a VALUE, just type the new value");
mvwaddstr(win,23,0,"To replace single DIGIT(s), use the SPACE BAR to move cursor");
wmove(win,y,x-1);
mvcurs(riptr,0,sched,2,1,1,1);
while(TRUE)
{
noecho();
key=wgetch(win);
if(key==CR) break;
if(key>=KDN)
  {
  /*put cursor over next group until non-arrow key hit#*/
  imv=jmv=0;
  mvcurs(riptr,1,sched,-1,1,1,1);
  }
else if(key>='-' && key<='9')
  repl_num(); /* uses std scan to get new # */
else if(key==SP)
  repl_dgt(); /* uses space to flag typeover, move cursor to digit(s) */
} /* end edit loop */
ilast=i; jlast=j;
ylast=y; xlast=x;
/*prtscr(0);*/
/* get next-step choice*/
y=xrych[1]=21; ijlim[3]=3; ijprv=-1;
wmove(win,yfmt,0);
wclrtobot(win);
wattron(win,A_STANDOUT);
mvwprintw(win,21,20,disp[0]);
mvwprintw(win,23,0,help[0]);
wattroff(win,A_STANDOUT);
mvwaddstr(win,21,0,"Next step:");
for(j=1,x=35; j<4; j++,x+=15)
  mvwprintw(win,y,x,disp[j]);
x=20; j=0;
wmove(win,21,x);
while(TRUE)
{
key=wgetch(win);
if(key==CR) break;
mvcurs(disp,-1,disp,15,1,0,1);
wmove(win,23,0);
wclrtoeol(win);
mvwprintw(win,23,0,help[j]);
wmove(win,y,x);
wrefresh(win);
}
wattroff(win,A_STANDOUT);
next=j;
if(next==1)
{
mvwprintw(win,23,0,"Saving edited file...");
wrefresh(win);
sleep(1);
fseek(upd,-79,1);
for(i=0; i<2; i++)
  fprintf(upd,"%7.2lf",tbl[i][0]);
fclose(upd);
} /* end file SAVE */
if(next != 0) break; /* 0 = MORE EDITS */
/* reset to last-edit state */
wmove(win,y,0);
wclrtobot(win);
i=ilast; j=jlast;
y=ylast; x=xlast;
} /*end MORE*/
if(next != 2) break; /* 2 = START OVER */
wmove(win,4,0);
wclrtobot(win);
} /*end GETDAT*/
endwin();
} /*end prog*/

The idea of not initializing because it works is alarming to me. One of my last trips overseas found many of the bugs tracked down to this issue. The reply was "it worked" is not a good one. Their staff tests with a handful of devices and the issues we were seeing were from the field of 40,000 devices. Light reading of this at http://blog.codinghorror.com/for-best-results-dont-initialize-variables/

The cost of that trip was in the 6 figures which was fine because if they had written it right I would have not had more experiences on the subject. That is, we've been here before.

Ok, I will initialize the screen. Being new to C cursor screens, and not having good code to rely on, what do I initalize the window to?

I found what I needed to initialize the window. Unfortunately, that did not solve the problem. The screen still will not come up when I select it from the menu. what I added to the code is the line: win = initscr(); . This line was added right after the last declaration in main, the line: double xprap,xnrap,lorap,hirap,solvpctchkinitial,solvpctchkmaximum; , and vefore the line: int iscrn=-1, idrow=0; ( and its comment). If you can find any other problems with this code, please let me know.

There are a number of issues with this, besides the fact that it is a Windows program. You need to create your main window: win = newwin(nlines, ncols, y0, x0);
Before that, you need to call the initscr(); function. Without those things, when I fixed it up (removed the Windows functions) I could build it on Linux, but as expected it dumped core.

I rewrote this screen using new logic. I copied and pasted portions of the above code I knew worked, and my rewritten screen does work properly. THank you for the suggestions.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.