Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

I want to print the first 70 characters of a string...

Status
Not open for further replies.

bgreen

Programmer
Feb 20, 2003
185
CA
Hi all,

I am not a c programmmer but was thrown into fixing a program. Below is the string sp_amount. Right now with code bellow the print out on the paper improperly.

sp_amount:

Ninety-Nine Million Nine Hundred Ninety-Nine Thousand Nine Hundred Ninety-Nine Dollars And 99 Cents

Prints like the following:

(1st line)
Ninety-Nine Million Nine Hundred Ninety-Nine Thousand Nine Hundred Ninety-Nine Dollars An
(second line)
Cents*************************************************

As you can see there is wording missing. If I change the position to move more to the left it prints properly. But, I would like to keep the position it is at right now and add a caridge return at the first blank character after the 70th character. Does anyone know how to do this. I have the code bellow.

Ideally it would look like this:
(1st line)
Ninety-Nine Million Nine Hundred Ninety-Nine Thousand Nine Hundred Ninety-Nine
(2nd)
Dollars And 99 Cents*******************************

/* if the string is less then 70 prints on first line followed by **** */

if (strlen(cheque.sp_amount) < 70)
{
memset(buf, '*', sizeof(buf));
buf[70] = NULL;
memcpy(buf, cheque.sp_amount, strlen (cheque.sp_amount));

POS(1);
fprintf(fd, "%s\r\n\r\n\r\n", buf);
}
else
{

/*if string longer then 70 print first 70 chars then caridge return and print on second line followed by **** */

ptr = strrchr(cheque.sp_amount, ' ');
*ptr = NULL;
ptr++;

POS(1);
fprintf(fd, "%s --\r\n", cheque.sp_amount);

memset(buf, '*', sizeof(buf));
buf[70] = NULL;
memcpy(buf, ptr, strlen(ptr));
POS(1.5);
fprintf(fd, "%s\r\n\r\n", buf);
}
 
Try this
Code:
#include <stdio.h>
#include <string.h>

int main ( ) {
    char seventy[] = "1234567890123456789012345678901234567890"
                     "123456789012345678901234567890";
    char buff[]    = "Ninety-Nine Million Nine Hundred Ninety-Nine"
                     " Thousand Nine Hundred Ninety-Nine"
                     " Dollars And 99 Cents";
    char *p;
    int  i;

    /* just a ruler for testing */
    printf( "%s\n", seventy );
    
    /* format line into 1 or 2 lines */
    if ( strlen(buff) < 70 || (p = strchr( buff+70, ' ' )) == NULL ) {
        /* a short line, */
        /* or a slightly long line with no space after the 70th char */
        printf( "%s", buff );
        i = strlen(buff);
    } else {
        /* long line with a space found, blank the space and print 2 lines */
        *p++ = '\0';
        printf( "%s\n%s", buff, p );
        i = strlen(p);
    }
    while ( i++ < 70 ) putchar('*');
    putchar('\n');
    return 0;
}

--
 
Code:
printf("%.70s\n",str); // Static approach
// or dynamic:
int w = 70;
...
printf("%.*s\n",w,str);
 
Is there a way to do it with the code that I have provided.

This is just a snip of a full cheque printing program. What do I need to add or change to make the line which spells out the amount on two lines. Preferably 70 characters long at the most on the first line, the rest on the second line followed by *. If you look at the previous provided code if it is less then 70 it prints all on the first line but the else isn't working properly. It doesn't perform a caridge return when it gets to 70 characters. I would like to avoide cutting off words so it could be a little shorter to make sure that doesn't happen.


...

main(int argc, char *argv[])
{
FILE *fd;
char line[BUFSIZE], *temp_file, buf[80];

/*
* Initialize printer command strings.
*/
CnvrtStr(Init);
CnvrtStr(Micr);
CnvrtStr(SymbolSet);
CnvrtStr(DefaultFont);
CnvrtStr(PrettyFont);
CnvrtStr(Reset);
CnvrtStr(Half);

TransitNum = ROYAL_TRANSIT_NUM;
AccountNum = ROYAL_ACCOUNT_NUM;

/*
* Create temporary file.
*/
temp_file = tmpnam(NULL);
fd = fopen(temp_file, "w+");

/*
* Ignore Escape sequences from Oracle. Send ours.
*/
/* UPG7.0.1 The GetLine function did not work properly after the upgrade.
It was causing a segmentation fault. It had something to do with the
data coming from stdin not having the same termination characters. I
attempted to change GetLine, but had no success. Rather than use
GetLine I decided to use fgets.
*/


/* GetLine(line); */
fprintf(fd, "%s", Init);

/* while (GetLine(line)) */
while (fgets(line, sizeof(line), stdin) != NULL)
{
strncpy(buf, StrTrm(line), 2);
buf[2] = NULL;

/*fprintf(fd, "(%s)\n", line);*/
switch(atoi(buf))
{
case 1:
strcpy(cheque.date, &line[18]);
break;

case 2:
strcpy(cheque.amount, &line[18]);
break;

case 3:
strcpy(cheque.sp_amount, &line[18]);
break;

case 4:
strcpy(cheque.num, &line[18]);
break;

case 5:
strcpy(cheque.name, &line[18]);
break;

case 6:
strcpy(cheque.address1, &line[18]);
break;

case 7:
strcpy(cheque.address2, &line[18]);
break;

case 8:
strcpy(cheque.address3, &line[18]);
break;

case 9:
strcpy(cheque.city, &line[18]);
break;

case 10:
strcpy(cheque.prov, &line[18]);
break;

case 11:
strcpy(cheque.postal, &line[18]);
break;

case 20:
strcpy(invoice_num, &line[18]);
break;

case 21:
strcpy(desc1, &line[18]);
/* fprintf(fd, "desc1(%s)\n", desc1); */
break;

case 22:
strcpy(desc2, &line[18]);
/* fprintf(fd, "desc2(%s)\n", desc2); */
break;

case 23:
strcpy(desc3, &line[18]);
/* fprintf(fd, "desc3(%s)\n", desc3); */
break;

case 24:
strcpy(desc4, &line[18]);
/* fprintf(fd, "desc4(%s)\n", desc4); */
break;

case 25:
strcpy(desc5, &line[18]);
/* fprintf(fd, "desc5(%s)\n", desc5); */
break;

case 26:
strcpy(desc6, &line[18]);
/* fprintf(fd, "desc6(%s)\n", desc6); */
break;

case 27:
strcpy(desc7, &line[18]);
/* fprintf(fd, "desc7(%s)\n", desc7); */
break;

case 28:
strcpy(desc8, &line[18]);
/* fprintf(fd, "desc8(%s)\n", desc8); */
break;

case 29:
strcpy(desc9, &line[18]);
/* fprintf(fd, "desc9(%s)\n", desc9); */
break;

/* case 30 used for manual cheq descptions */
case 30:
strcpy(desc10, &line[18]);
/* fprintf(fd, "desc10(%s)\n", desc10); */

if (strlen(StrTrm(desc1)) == 0)
{
strcpy(desc1, desc10);
}


break;

case 99:
FormatCheque(fd, invoice_num);
DetailLines(fd);

strcpy(desc1, " ");
strcpy(desc2, " ");
strcpy(desc3, " ");
strcpy(desc4, " ");
strcpy(desc5, " ");
strcpy(desc6, " ");
strcpy(desc7, " ");
strcpy(desc8, " ");
strcpy(desc9, " ");
strcpy(desc10, " ");

break;

default:
break;
}
}

/*
* Reset printer.
*/
fprintf(fd, "%s", Reset);

/*
* Close temp file.
*/
fclose(fd);

/*
* Print temp file created with args passed via argv[].
*/
LpCmd(argc, argv, temp_file);

/*
* Remove temp file.
*/
unlink(temp_file);
}


/*
* GetLine() - This routine reads from standard input a block of data at a
* time. It then parses logical lines from the block of data
* into another buffer reading another block of data when needed.
* This logical line length is then returned. If there is no
* more data to read the routine returns zero.
*/
GetLine(char *buf)
{
static char block[BUFSIZE];
static int bytes = -1;
static int pos;
int len, i;

len = 0;

if (bytes < 0) /* If first time read block of data in. */
{
if ((bytes = fread(block, 1, sizeof(block), stdin)) <= 0)
return(len);

pos = 0;
}

do {
if (pos < bytes) /* Copy byte is data left in block area. */
{
buf[len] = block[pos];
len++;
}
else /* Read new block of data in. */
{
if ((bytes = fread(block, 1, sizeof(block), stdin)) <= 0)
return(0);

pos = 0;
buf[len] = block[pos];
len++;
}
} while (block[pos++] != NULL);

return(len); /* Return logical record length. */
}


/*
*
*/
FormatCheque(FILE *fd)
{
char buf[80], *ptr;
int n;

fprintf(fd, "\r\n\r\n\r\n\r\n");

POS(4.32);
fprintf(fd, "%s", cheque.date);

POS(5.36);
fprintf(fd, "%10.10s", cheque.num);

memset(buf, '*', sizeof(buf));
strcpy(&buf[14 - strlen(cheque.amount)], cheque.amount);
POS(6.5);
fprintf(fd, "%s%s", PrettyFont, buf);

fprintf(fd, "\r\n\r\n\r\n");

if (strlen(cheque.sp_amount) < 70)
{
memset(buf, '*', sizeof(buf));
buf[70] = NULL;
memcpy(buf, cheque.sp_amount, strlen(cheque.sp_amount));

POS(1);
fprintf(fd, "%s\r\n\r\n\r\n", buf);
}
else
{
ptr = strrchr(cheque.sp_amount, ' ');
*ptr = NULL;
ptr++;

POS(1);
fprintf(fd, "%s --\r\n", cheque.sp_amount);

memset(buf, '*', sizeof(buf));
buf[70] = NULL;
memcpy(buf, ptr, strlen(ptr));
POS(1.5);
fprintf(fd, "%s\r\n\r\n", buf);
}
...
 
Here's a liitle update:

I changed the line
ptr = strrchr(cheque.sp_amount, ' '); in the else statement to:
ptr = strrchr(cheque.sp_amount, '\0');

This prints the whole line on the first line and the second line all *. If I could do a caridge return after the word Dollars that would be good.


else
{

/*if string longer then 70 print first 70 chars then caridge return and print on second line followed by **** */

ptr = strrchr(cheque.sp_amount, ' ');

*ptr = NULL;
ptr++;

POS(1);
fprintf(fd, "%s --\r\n", cheque.sp_amount);

memset(buf, '*', sizeof(buf));
buf[70] = NULL;
memcpy(buf, ptr, strlen(ptr));
POS(1.5);
fprintf(fd, "%s\r\n\r\n", buf);
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top