Link to home
Start Free TrialLog in
Avatar of mkido
mkido

asked on

Reverse printing many files. At once.

Hello everyone, this is an extention of previous posting,

The study note of k&R pg 108-110.   I introduced the multiple files reading/writing by additional

   firstwd.c    (<- to capture the filename in "header.txt")
   header.txt  (<-  in here, a list of filenames)

The main codes are previsouly posted and again here,
   1.   PRO145.c
   2.   getline.c
   3.   readlines.c
   4.   writelines.c
   5.   alloc.c

Compiled altogether.

   sample file = "AL-LIB1.TXT", "CA-LIB3.TXT"
   Should write files in "Result" folder, the same name.

It compiles well, and reverse only the first filename in "header.txt" list, namely, AL-LIB1.TXT (20KB).   The error said,

   error: input too big to sort

This suggests that I need to use set MEMORY FREE to have another file.    Such as afree(), free().    I tried a few times, but I can't figure it out.    Please help !!!   Thank you !!!   By the way, afree() in the text is

void afree(char *p)
{
   if (p >= allocbuf && p <allocbuf + ALLOCSIZE)
          allocp = p;
}

I didn't use this at all, because I don't know how and where to use this.    The rest of below (.c) are compiled all together.



===========================
/* firstwd.c */
/* Recyclable Object.        */

#include <ctype.h>

extern char *firstwd (char *to, char *from)
{
   while (isspace(*from) && *from!='\0') ++from;
   while (!isspace(*from) && *from!='\0') *to++ = *from++;
   *to = '\0';
   return (from);
}

===   file "Header.txt"  ==========
AL-LIB1R.TXT
CA-LIB3R.TXT




================
/* PRO145.C */
/* Store lines into *lineptr, and print them Upside-down       */
/* Origirnally << Line Sorting by using lineptr (line pointer) */
/* K&R pg 107, 5.6 */
/* I don't understand details.  I just copied from the text.   */
/* And it just works fine.                                     */


#include <stdio.h>
#include <string.h>
#include <alloc.h>
#define MAXLINES 5000   /* max #lines to be sorted */

char *lineptr[MAXLINES];  /* pointers to text lines */
FILE *infp, *outfp;

char openingFile [64];
char openedFN    [64];
char writingFile [64];

int readlines(FILE *infp, char *lineptr[], int nlines);
void writelines(FILE *outfp, char *lineptr[], int nlines);
extern char *firstwd (char *to, char *from);


int main(void)
{

   FILE *infpFN;
   infpFN=fopen ("HEADER.TXT", "r");


   while( (fgets(openingFile, 64, infpFN))!=NULL )
   {
         int nlines;   /* number of input lines read */
         nlines=0;

         firstwd (openedFN, &openingFile[0]);   /* This firstwd() is important to capture the filename */
         infp=fopen ( openedFN, "r");
         sprintf(writingFile, "RESULT\\%s", openedFN);
         outfp=fopen( writingFile, "w");

         if ((nlines=readlines(infp, lineptr, MAXLINES)) >= 0) {
                  writelines(outfp, lineptr, nlines);
                  return 0;
         } else {
                  printf("error: input too big to sort\n");
                  return 1;
         }   /* Closing IF-ELSE loop */
   }       /* Closing WHILE loop <- One-by-One file */
   return 0;
}          /* Closing main() */


=============
/* readlines.c */
/* "readlines.c" is a subroutine, not the main PRO145.c,   */
/*     but almost the main part in this program.           */
/* K&R, pg 109 */

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXLEN 1000   /* max length of any input line */
int getline(FILE *infp, char *, int);
char *alloc(int);

/* readline: read input lines */
int readlines(FILE *infp, char *lineptr[], int maxlines)
{
   int len, nlines;
   char *p, line[MAXLEN];

   nlines = 0;
   while ( (len=getline(infp, line, MAXLEN)) > 0)
   {
        if ( nlines >= maxlines || (p = alloc(len))==NULL ) {
             return -1;
        } else {
             line[len-1] = '\0'; /* delete newline */
             strcpy(p, line);
             lineptr[nlines++] = p;
        }
   }
   printf("No of lines : %d\n\n", nlines);    /* DEBUG */
   return nlines;
}


================
/* getline.c : read a line into s, return length */
/* K & R, page 29 */

#include<stdio.h>

int getline(FILE *infp, char s[], int lim)
{
   int c, i;

   for (i=0; i<lim-1 && (c=getc(infp))!=EOF && c!='\n'; ++i)
        s[i] = c;
   if (c== '\n') {
        s[i] = c;
        ++i;
   }
   s[i] = '\0';
   return i;
}


===============
/* writelines.c :  reverse writing output lines */

#include<stdio.h>
#include<alloc.h>

void writelines (FILE *outfp, char *lineptr[], int nlines)
{
   int i;

   for ( i = (nlines-1); i > -1; i--)     /* Reverse Print */
   {
        fprintf(outfp, "%s\n", lineptr[i]);
   }
}


==================
/* alloc:  Allocate Size */

#define ALLOCSIZE 30000   /* size of available space, 19K O.K. */

static char allocbuf[ALLOCSIZE];  /* storage for alloc */
static char *allocp = allocbuf;   /* next free position */

char *alloc(int n)   /* return pointer to n characters */
{
   if (allocbuf + ALLOCSIZE - allocp >= n) {    /* it fits */
        allocp += n;
        return allocp -n;  /* old p */
   } else       /* not enough room */
        return 0;
}


=================

END
Avatar of mkido
mkido

ASKER

Previous posting is,

https://www.experts-exchange.com/questions/21727864/Reverse-printing-of-input-file-by-Pointer-C-Program.html

By ozo's comment, it works well at one file each.
ASKER CERTIFIED SOLUTION
Avatar of PaulCaswell
PaulCaswell
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mkido

ASKER

I tried the below,

        if ((nlines=readlines(infp, lineptr, MAXLINES)) >= 0) {
               writelines(outfp, lineptr, nlines);
               afree(p);
        //       return 0;
        } else {
               printf("error: input too big to sort\n");
               return 1;
        }   /* Closing IF-ELSE loop */


Then I compiled "afree()" together.  
void afree(char *p)
{
   if (p >= allocbuf && p <allocbuf + ALLOCSIZE)
          allocp = p;
}

Unfortunately, this measure didn't work.   Does anyone explain a little bit about, the below,
(in alloc)
   if (allocbuf + ALLOCSIZE - allocp >= n) {    /* it fits */

AND
(in afree)
    if (p >= allocbuf && p <allocbuf + ALLOCSIZE)

I hardly understand what those lines mean.   Thank you for your help!!

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mkido

ASKER

Hello!   PaulCaswell!

It's wonderful!   I understood what those lines say.   Now, let me think what I should do to fix the program.   It take a little while.   Bye now.
Avatar of mkido

ASKER

Now, I have another question:  in afree(), I saw
   allocp = p;
if p 'pointer' points to something in the allocation block.   Why does this releases the storage which is acuired, so it can be re-used later (according to text, K&R, pg. 100+102)?  

(Refrence)
void afree(char *p)
{
   if (p >= allocbuf && p <allocbuf + ALLOCSIZE)
          allocp = p;
}
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
cwwkie,

>>    afree(buffer1);

wouldnt

afree(lineptr[0]);

be a bit safer :-)

Paul  
Avatar of mkido

ASKER

Well, with Afree, and with afree(lineptr[0]), it compiles well.   However, still it does only the first file in the list (header.txt).   Let me think.
Paul,

I did not receive an email notification of your comment, but

>> wouldnt  
>>   afree(lineptr[0]);  
>> be a bit safer :-)

I was just trying to explain how afree worked, unrelated to the code in the question...
Maybe I should have made that a bit more clear.
cwwkie,

>>I did not receive an email notification of your comment, but
They've been messing with e-mail today. Perhaps you fell foul of that.

>>I was just trying ...
Sorry! I didnt mean to sound critical. I shouldnt really have got involved really, you are doing fine here. :-)

Paul
>> Sorry! I didnt mean to sound critical. I shouldnt really have got involved really, you are doing fine here. :-)
Thank you, but I can cope with criticism very well. There is a saying here in holland which translates to something like "someone who has never changed his mind, has never learned something".  ;-)

And if someone shouldn't mix in, I think that would be me. You were doing very well too! :-))
and now back to mkido,

>>However, still it does only the first file in the list (header.txt).   Let me think.
If you need help, just let us know.

You can use printf statements to see what is executed, for example:
  printf("now executing line %d\n", __LINE__);

If you add that where you read the file (header.txt), you can see on the screen how many times it is executed, and where the problem might be.
Avatar of mkido

ASKER

Dear cwwkie,

I carefully read your long explanation about alloc() and afree() again today.   That makes me very clear conceptually.   It is very good explanation.    This is the first time I struggle with MEMORY STORAGE SPACE, so let me have a little more time to try a few things.   Thank you both "PaulCaswell" and "cwwkie".  
Just a little test.
If you understand how alloc and afree are working, do you also understand what happens if you do this:

int main(void)
{
    char *a;
    char *b;
    a = alloc(5);
    b = alloc(5);
    afree(a);
    afree(b);
}

In K&R p.100+101 it is explained that this is not allowed. But do you understand why?
Avatar of mkido

ASKER

Well cwwkie,

alloc(5) is applied to a pointer which advances 5 consecutive character positions, saving 5 character storage space.   char *a, char *b are character variables, and they are not pointers.   So, that is not allowed.   I re-read the K&R .p100_101, I didn't see the exact paragraph about "not allowed" reason.   Mine is the second edition (ANSI-C stamp).    Whether or not my answer is right or faulse, if you don't mind, give me a few another explanation or a little crucial tests for me to understand better, if you have time.    Thanks.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mkido

ASKER

Hi!   cwwkie, thank you!!    I found the sentence "a stack, or last-in, first-out" at pg 100-101.   Very good.   I didn't understand the meaning of that sentence in the text.  

Well, frankly speaking, I am still very vague about the Pointers.   Let me try the page 99's (text) strlen().   The text said "char *s", s is a pointer.   In that case, s++ increments 1-byte 1-byte each time on the memory?   Stepping forward?   I will be back after I play around the strlen() codes.

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mkido

ASKER

I just reviewed Ted Jensen's tutoiral pages.   It looks very nice.   Excuse me I haven't got back soon here.    I did another posting to my business site.   The purpose is different though.   Mine has more practial aspect.   Let me take time for me to study Jensen's site.    By the way, does a newer compiler of C or C++ have easy or bigger MEMORY size as a default.   Does the size of MEMORY depend on OS or Compiler's setting?    Just a few chats.
Avatar of mkido

ASKER

Thank you all.    I will carefully read Ted Jensen's Pointers.