We help IT Professionals succeed at work.

Reverse printing many files.   At once.

mkido
mkido asked
on
283 Views
Last Modified: 2010-04-15
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
Comment
Watch Question

Author

Commented:
Previous posting is,

https://www.experts-exchange.com/Programming/Programming_Languages/C/Q_21727864.html

By ozo's comment, it works well at one file each.
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
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!!

This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
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.

Author

Commented:
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;
}
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
cwwkie,

>>    afree(buffer1);

wouldnt

afree(lineptr[0]);

be a bit safer :-)

Paul  

Author

Commented:
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.

Commented:
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

Commented:
>> 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! :-))

Commented:
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.

Author

Commented:
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".  

Commented:
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?

Author

Commented:
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.
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
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.

Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION

Author

Commented:
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.

Author

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

Gain unlimited access to on-demand training courses with an Experts Exchange subscription.

Get Access
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Empower Your Career
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE

Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.