Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #67655 > unrolled thread

Reading beyond the end of file

Started byjanus <emekamicro@gmail.com>
First post2015-08-17 16:24 -0700
Last post2015-08-18 13:24 -0700
Articles 12 — 6 participants

Back to article view | Back to comp.lang.c


Contents

  Reading beyond the end of file janus <emekamicro@gmail.com> - 2015-08-17 16:24 -0700
    Re: Reading beyond the end of file Bartc <bc@freeuk.com> - 2015-08-18 00:53 +0100
      Re: Reading beyond the end of file Keith Thompson <kst-u@mib.org> - 2015-08-17 18:44 -0700
        Re: Reading beyond the end of file Tim Rentsch <txr@alumni.caltech.edu> - 2015-09-06 14:41 -0700
          Re: Reading beyond the end of file Keith Thompson <kst-u@mib.org> - 2015-09-06 17:09 -0700
    Re: Reading beyond the end of file James Kuyper <jameskuyper@verizon.net> - 2015-08-17 20:10 -0400
      Re: Reading beyond the end of file janus <emekamicro@gmail.com> - 2015-08-18 00:54 -0700
        Re: Reading beyond the end of file janus <emekamicro@gmail.com> - 2015-08-18 01:43 -0700
        Re: Reading beyond the end of file James Kuyper <jameskuyper@verizon.net> - 2015-08-18 10:18 -0400
        Re: Reading beyond the end of file Barry Schwarz <schwarzb@dqel.com> - 2015-08-18 09:18 -0700
          Re: Reading beyond the end of file Keith Thompson <kst-u@mib.org> - 2015-08-18 11:17 -0700
            Re: Reading beyond the end of file Barry Schwarz <schwarzb@dqel.com> - 2015-08-18 13:24 -0700

#67655 — Reading beyond the end of file

Fromjanus <emekamicro@gmail.com>
Date2015-08-17 16:24 -0700
SubjectReading beyond the end of file
Message-ID<b62ba036-de31-4f37-aaad-3d1372d40d3f@googlegroups.com>
Hello All,

I am not getting the expected result from the below code whenever I change '\0' to EOF. I noticed that the below will read pass the end of file. What is it that I am doing wrong? Could someone help me out?

static tokens* tokenize(char* source)
{
    int ch;
    tokens *ntoken;
    char* ctemp;
    //printf("%s\n",source);
    while((ch = *source++) != '\0')
    {

       while(isspace(ch))
        {
          ch = *source;
          source++;
        }
      if(ch == '\0')
      {
          printf("Dont break my heart\n ");
          break;
      }
       switch(ch)
       {
       case '+':
        {

            ntoken = tokenmem();
            ntoken->type = obplus;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, "+", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);
            break;
        }
       case '-':
        {
            ntoken = tokenmem();
            ntoken->type = obminus;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, "-", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);
            break;

        }
       case '#':
        {
            ntoken = tokenmem();
            ntoken->type = obneg;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, "#", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);

          break;
        }
       case '&':
        {
            ntoken = tokenmem();
            ntoken->type = oband;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, "&", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);

          break;
        }
       case '=':
        {
            ntoken = tokenmem();
            ntoken->type = eql;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, "=", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);

           break;
        }
       case '*':
        {
            ntoken = tokenmem();
            ntoken->type = obtimes;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, "*", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);
           break;
        }
       case '<':
        {
           ntoken = tokenmem();
           if(*source == '=')
           {
            ntoken->type = obleq;
            ctemp = (char *)malloc(sizeof(char)*3);
            strncpy(ctemp, "<=", 2);
            ctemp[2] = '\0';
            ntoken->txt = ctemp;
            source++;

           }
           else
           {
            ntoken->type = oblss;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, "<", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;


           }
           addtokentolist(ntoken);
           break;
        }
       case '>':
        {
            ntoken = tokenmem();
            if(*source == '=')
            {
            ntoken->type = obgeq;
            ctemp = (char *)malloc(sizeof(char)*3);
            strncpy(ctemp, ">=", 2);
            ctemp[2] = '\0';
            ntoken->txt = ctemp;
            source++;
            }
            else
            {
            ntoken->type = obgtr;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, ">", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;

            }
            addtokentolist(ntoken);

           break;
        }
       case ':':
        {
            ntoken = tokenmem();
            ntoken->type = obcolon;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, ":", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);
           break;
        }
       case ';':
        {
            ntoken = tokenmem();
            ntoken->type = obsemicolon;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, ";", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);
          break;
        }
       case '.':
        {
            ntoken = tokenmem();
            ntoken->type = period;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, ".", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);


            //return hlist;
           break;
        }
       case ']':
        {
            ntoken = tokenmem();
            ntoken->type = rbrak;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, "]", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);
           break;
        }
       case '[':
        {
            ntoken = tokenmem();
            ntoken->type = lbrak;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, "[", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);

           break;
        }
       case '(':
        {
            if (*source == '*')
            {
                source++;
                while (*source == ')')
                {
                    source++;
                }
            }
            else
            {
            ntoken = tokenmem();
            ntoken->type = lparen;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, "(", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);
            }

           break;
        }
       case ')':
        {
            ntoken = tokenmem();
            ntoken->type = rparen;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, ")", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
            addtokentolist(ntoken);
           break;
        }
       case '~':
        {
            ntoken = tokenmem();
            ntoken->type = obnot;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, "~", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
           break;
        }
       case ',':
        {
            ntoken = tokenmem();
            ntoken->type = obcomma;
            ctemp = (char *)malloc(sizeof(char)*2);
            strncpy(ctemp, ",", 1);
            ctemp[1] = '\0';
            ntoken->txt = ctemp;
           break;
        }
       default:
        {
            if(isdigit(ch))
            {
                int tnum = 0;
                tnum = tnum * 10 + ch - '0';
                //source++ ;
                ch = *source;
                while(isdigit(ch))
                {

                    tnum = tnum * 10 + ch - '0';
                    source++;
                    ch = *source;
                }

                ntoken = tokenmem();
                ntoken->type = obnum;
                ntoken->inttoken = tnum;
                addtokentolist(ntoken);

            }
            else if (isalpha(ch))
            {
                char* ntemp = source - 1;
                int cstr = 1;
                //source++;
                int cstate = 0;
                int i ;
                //source++;
                ch = *source;
                while(isalnum(ch))
                {
                    source++;
                    ch = *source;
                    cstr++;
                }

                if(cstr > IdLen)
                {
                    cstr = IdLen;
                }
                ctemp = (char *)malloc(sizeof(char)*(cstr + 1));
                strncpy(ctemp, ntemp, cstr);
                ctemp[cstr] = '\0';
                printf("%s string length (chars) ::%d\n", ctemp, cstr);
                ntoken = tokenmem();

                for(i = 0; i < kwlen; i++ )
                {
                    if(strcmp(keytab[i].kw, ctemp) == 0)
                    {
                        ntoken->type = keytab[i].ksym;
                        ntoken->txt = ctemp;
                        cstate = 1;
                        break;

                    }
                }
                if(!cstate)
                {
                    ntoken->type = ident;
                    ntoken->txt = ctemp;
                }

                addtokentolist(ntoken);


            }
            break;
        }
       }

    }
    //char* vv = source - 300;
    //printf("\nMy last card %s\n", vv);
    return hlist;
}


Regards, \Janus

[toc] | [next] | [standalone]


#67659

FromBartc <bc@freeuk.com>
Date2015-08-18 00:53 +0100
Message-ID<mqts2p$js0$1@dont-email.me>
In reply to#67655
On 18/08/2015 00:24, janus wrote:
> Hello All,
>
> I am not getting the expected result from the below code whenever I change '\0' to EOF. I noticed that the below will read pass the end of file. What is it that I am doing wrong? Could someone help me out?

What's the input format? Is it a string terminated with \0, or with EOF?

Note that EOF, normally set to -1, might not be properly representable 
when the 'char' type is unsigned (it will be 255). It might work, but I 
think 0 is a better terminator if it's going to be a char value.

> static tokens* tokenize(char* source)
> {
>      int ch;
>      tokens *ntoken;
>      char* ctemp;
>      //printf("%s\n",source);
>      while((ch = *source++) != '\0')

It probably doesn't matter, as ch is checked, but you allow source to 
point past the 0/EOF character. I wouldn't advance source past the 
terminator, just in case some code then tries to use *source.

Perhaps temporarily use a function to obtain the next character from 
source (a bit fiddly, it needs to take a char** parameter so that it can 
update the source pointer within the function), then it is easier to 
stop it going past the EOF point.

-- 
Bartc

[toc] | [prev] | [next] | [standalone]


#67667

FromKeith Thompson <kst-u@mib.org>
Date2015-08-17 18:44 -0700
Message-ID<lnk2st4bg0.fsf@kst-u.example.com>
In reply to#67659
Bartc <bc@freeuk.com> writes:
> On 18/08/2015 00:24, janus wrote:
>> I am not getting the expected result from the below code whenever I
>> change '\0' to EOF. I noticed that the below will read pass the end
>> of file. What is it that I am doing wrong? Could someone help me out?
>
> What's the input format? Is it a string terminated with \0, or with EOF?
>
> Note that EOF, normally set to -1, might not be properly representable 
> when the 'char' type is unsigned (it will be 255). It might work, but I 
> think 0 is a better terminator if it's going to be a char value.

EOF is the value returned by getchar() and related functions when they
encounter an end-of-file condition.

(Strictly speaking, it's a macro that expands to a constant expression
whose value is as I described.)

It never makes sense to store the value EOF in a char, signed char, or
unsigned char object.  It's intended as an in-band signal, distinct from
any valid input character.  getchar(), for example, returns an input
character interpreted as an unsigned char (and therefore >= 0) *or* the
value EOF (guaranteed to be negative).  If the input happens to have a
value of -1 when interpreted as a signed char, getchar() will return 255
(assuming CHAR_BIT==8).

[...]

C strings are by definition terminated by a `'\0'` character.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#69682

FromTim Rentsch <txr@alumni.caltech.edu>
Date2015-09-06 14:41 -0700
Message-ID<kfnbndfql81.fsf@x-alumni2.alumni.caltech.edu>
In reply to#67667
Keith Thompson <kst-u@mib.org> writes:

> Bartc <bc@freeuk.com> writes:
>> On 18/08/2015 00:24, janus wrote:
>>> I am not getting the expected result from the below code whenever I
>>> change '\0' to EOF.  I noticed that the below will read pass the end
>>> of file.  What is it that I am doing wrong?  Could someone help me out?
>>
>> What's the input format?  Is it a string terminated with \0, or with EOF?
>>
>> Note that EOF, normally set to -1, might not be properly representable 
>> when the 'char' type is unsigned (it will be 255).  It might work, but I 
>> think 0 is a better terminator if it's going to be a char value.
>
> EOF is the value returned by getchar() and related functions when they
> encounter an end-of-file condition.
>
> (Strictly speaking, it's a macro that expands to a constant expression
> whose value is as I described.)
>
> It never makes sense to store the value EOF in a char, signed char, or
> unsigned char object.  It's intended as an in-band signal, distinct from
> any valid input character.  [snip]

Presumably you meant to say out-of-band rather than in-band.

[toc] | [prev] | [next] | [standalone]


#69700

FromKeith Thompson <kst-u@mib.org>
Date2015-09-06 17:09 -0700
Message-ID<lnsi6rt7id.fsf@kst-u.example.com>
In reply to#69682
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Bartc <bc@freeuk.com> writes:
>>> On 18/08/2015 00:24, janus wrote:
>>>> I am not getting the expected result from the below code whenever I
>>>> change '\0' to EOF.  I noticed that the below will read pass the end
>>>> of file.  What is it that I am doing wrong?  Could someone help me out?
>>>
>>> What's the input format?  Is it a string terminated with \0, or with EOF?
>>>
>>> Note that EOF, normally set to -1, might not be properly representable 
>>> when the 'char' type is unsigned (it will be 255).  It might work, but I 
>>> think 0 is a better terminator if it's going to be a char value.
>>
>> EOF is the value returned by getchar() and related functions when they
>> encounter an end-of-file condition.
>>
>> (Strictly speaking, it's a macro that expands to a constant expression
>> whose value is as I described.)
>>
>> It never makes sense to store the value EOF in a char, signed char, or
>> unsigned char object.  It's intended as an in-band signal, distinct from
>> any valid input character.  [snip]
>
> Presumably you meant to say out-of-band rather than in-band.

No, I meant to say in-band.  It's possible I misused the term, but I
don't think so.

Calling getchar() repeatedly gives you a sequence of int values.  Most
of those values are going to represent character values in the range
0..UCHAR_MAX.  The value EOF in the same sequence does not represent a
character value.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#67660

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-08-17 20:10 -0400
Message-ID<55D277F4.5090905@verizon.net>
In reply to#67655
On 08/17/2015 07:24 PM, janus wrote:
> Hello All,
> 
> I am not getting the expected result from the below code whenever I change '\0' to EOF. ... 

That's because you had incorrect expectations about what the result
would be. Was that a helpful response? If not, it's because you haven't
given us enough information to give you a more helpful response. You
should describe what inputs you used when you got unexpected results,
and what you expected the result to be, with an emphasis on the details
of how the expected result differed from the actual result.

> ... I noticed that the below will read pass the end of file. What is it that I am doing wrong? Could someone help me out?

The code you provided doesn't contain any calls to any routines that
involve files - nothing that opens them, reads them, writes them or
closes them. Therefore, it's not at all clear what the connection is
between your subject line, the above question, and this code. If your
problem does actually involve reading from a file, you need to show us
the part of your code that actually performs the read.

The code you provided relies upon the definition of the following
identifiers:
	tokens
	    type
	    txt
	    inttoken
	tokenmem
	addtokentolist
	keytab
	obplus
	obminus
	obneg
	oband
	eql
	obtimes
	obleq
	oblss
	obgeq
	obgtr
	obcolon
	obsemicolon
	period
	rbrak
	lbrak
	lparen
	rparen
	obnot
	obcomma
	obnum
	IdLen
	kwlen
	keytab
	ident
	hlist

The problem you're running into might depend upon an error in the
definition of one or more of those things - in which case we won't be
able to help you unless you provide us with those definitions. If you're
sure that one or more of those things is irrelevant, then remove the
thing that you think is irrelevant, and see if you can still reproduce
the problem. We need to see the definition of any item that you can't
remove.

[toc] | [prev] | [next] | [standalone]


#67681

Fromjanus <emekamicro@gmail.com>
Date2015-08-18 00:54 -0700
Message-ID<691ee45c-f295-4c1d-bad8-7a7cde1f5142@googlegroups.com>
In reply to#67660
On Tuesday, August 18, 2015 at 1:10:37 AM UTC+1, James Kuyper wrote:
> On 08/17/2015 07:24 PM, janus wrote:
> > Hello All,
> > 
> > I am not getting the expected result from the below code whenever I change '\0' to EOF. ... 
> 
> That's because you had incorrect expectations about what the result
> would be. Was that a helpful response? If not, it's because you haven't
> given us enough information to give you a more helpful response. You
> should describe what inputs you used when you got unexpected results,
> and what you expected the result to be, with an emphasis on the details
> of how the expected result differed from the actual result.
> 
> > ... I noticed that the below will read pass the end of file. What is it that I am doing wrong? Could someone help me out?
> 
> The code you provided doesn't contain any calls to any routines that
> involve files - nothing that opens them, reads them, writes them or
> closes them. Therefore, it's not at all clear what the connection is
> between your subject line, the above question, and this code. If your
> problem does actually involve reading from a file, you need to show us
> the part of your code that actually performs the read.
> 
> The code you provided relies upon the definition of the following
> identifiers:
> 	tokens
> 	    type
> 	    txt
> 	    inttoken
> 	tokenmem
> 	addtokentolist
> 	keytab
> 	obplus
> 	obminus
> 	obneg
> 	oband
> 	eql
> 	obtimes
> 	obleq
> 	oblss
> 	obgeq
> 	obgtr
> 	obcolon
> 	obsemicolon
> 	period
> 	rbrak
> 	lbrak
> 	lparen
> 	rparen
> 	obnot
> 	obcomma
> 	obnum
> 	IdLen
> 	kwlen
> 	keytab
> 	ident
> 	hlist
> 
> The problem you're running into might depend upon an error in the
> definition of one or more of those things - in which case we won't be
> able to help you unless you provide us with those definitions. If you're
> sure that one or more of those things is irrelevant, then remove the
> thing that you think is irrelevant, and see if you can still reproduce
> the problem. We need to see the definition of any item that you can't
> remove.


















On Tuesday, August 18, 2015 at 1:10:37 AM UTC+1, James Kuyper wrote:
> On 08/17/2015 07:24 PM, janus wrote:
> > Hello All,
> > 
> > I am not getting the expected result from the below code whenever I change '\0' to EOF. ... 
> 
> That's because you had incorrect expectations about what the result
> would be. Was that a helpful response? If not, it's because you haven't
> given us enough information to give you a more helpful response. You
> should describe what inputs you used when you got unexpected results,
> and what you expected the result to be, with an emphasis on the details
> of how the expected result differed from the actual result.
> 
> > ... I noticed that the below will read pass the end of file. What is it that I am doing wrong? Could someone help me out?
> 
> The code you provided doesn't contain any calls to any routines that
> involve files - nothing that opens them, reads them, writes them or
> closes them. Therefore, it's not at all clear what the connection is
> between your subject line, the above question, and this code. If your
> problem does actually involve reading from a file, you need to show us
> the part of your code that actually performs the read.
> 
> The code you provided relies upon the definition of the following
> identifiers:
> 	tokens
> 	    type
> 	    txt
> 	    inttoken
> 	tokenmem
> 	addtokentolist
> 	keytab
> 	obplus
> 	obminus
> 	obneg
> 	oband
> 	eql
> 	obtimes
> 	obleq
> 	oblss
> 	obgeq
> 	obgtr
> 	obcolon
> 	obsemicolon
> 	period
> 	rbrak
> 	lbrak
> 	lparen
> 	rparen
> 	obnot
> 	obcomma
> 	obnum
> 	IdLen
> 	kwlen
> 	keytab
> 	ident
> 	hlist
> 
> The problem you're running into might depend upon an error in the
> definition of one or more of those things - in which case we won't be
> able to help you unless you provide us with those definitions. If you're
> sure that one or more of those things is irrelevant, then remove the
> thing that you think is irrelevant, and see if you can still reproduce
> the problem. We need to see the definition of any item that you can't
> remove.

I use the below to read the entire file. And the result is what is feed to 
static tokens* tokenize(char* source) . However  because of the error I am getting I just decided to have something like this:

char* rdata = "the content of file"; //This is where I copied and pasted the content of my file. And because of this change, I changed EOF to '\0' in order to terminate a list of characters.  The code switch is virtually redundant to the issue at hand 
static char *frd (const char *fn) {

  FILE *R;
  char *contents;
  size_t fsize;
  size_t nrd;
  size_t ttsize;

  R = fopen(fn, "r");
  printf("Word Count: %d\n", meanSentenceLength(R));
  if (!R) {
    printf(fn);
    printf("\n");
    cerror(0, "Failed to open source file");
  }

  /* Get  file's size */
  fseek(R, 0, SEEK_END);
  fsize = ftell(R);
  fseek(R, 0, SEEK_SET);
  ttsize = fsize;
  fsize *= sizeof(char);

  printf("Size of bytes:: %d\n", ttsize);

  /* End marker*/
  contents = (char*)malloc(fsize + 1);
  cerror(contents, "Failed to create memory for array of characters");

  nrd = fread(contents, sizeof(char), 886, R);
  cerror((void *)nrd, "Failed to read the source file");
  contents[nrd] = '\0';

  if (fclose(R) == EOF) {
    cerror(0, "Closing of source file failed");

  }

 // printf("%s\n", contents);
  return contents;
}

[toc] | [prev] | [next] | [standalone]


#67686

Fromjanus <emekamicro@gmail.com>
Date2015-08-18 01:43 -0700
Message-ID<8daabea0-58f9-4458-89e8-44ca566a1b29@googlegroups.com>
In reply to#67681
On Tuesday, August 18, 2015 at 8:54:56 AM UTC+1, janus wrote:
> On Tuesday, August 18, 2015 at 1:10:37 AM UTC+1, James Kuyper wrote:
> > On 08/17/2015 07:24 PM, janus wrote:
> > > Hello All,
> > > 
> > > I am not getting the expected result from the below code whenever I change '\0' to EOF. ... 
> > 
> > That's because you had incorrect expectations about what the result
> > would be. Was that a helpful response? If not, it's because you haven't
> > given us enough information to give you a more helpful response. You
> > should describe what inputs you used when you got unexpected results,
> > and what you expected the result to be, with an emphasis on the details
> > of how the expected result differed from the actual result.
> > 
> > > ... I noticed that the below will read pass the end of file. What is it that I am doing wrong? Could someone help me out?
> > 
> > The code you provided doesn't contain any calls to any routines that
> > involve files - nothing that opens them, reads them, writes them or
> > closes them. Therefore, it's not at all clear what the connection is
> > between your subject line, the above question, and this code. If your
> > problem does actually involve reading from a file, you need to show us
> > the part of your code that actually performs the read.
> > 
> > The code you provided relies upon the definition of the following
> > identifiers:
> > 	tokens
> > 	    type
> > 	    txt
> > 	    inttoken
> > 	tokenmem
> > 	addtokentolist
> > 	keytab
> > 	obplus
> > 	obminus
> > 	obneg
> > 	oband
> > 	eql
> > 	obtimes
> > 	obleq
> > 	oblss
> > 	obgeq
> > 	obgtr
> > 	obcolon
> > 	obsemicolon
> > 	period
> > 	rbrak
> > 	lbrak
> > 	lparen
> > 	rparen
> > 	obnot
> > 	obcomma
> > 	obnum
> > 	IdLen
> > 	kwlen
> > 	keytab
> > 	ident
> > 	hlist
> > 
> > The problem you're running into might depend upon an error in the
> > definition of one or more of those things - in which case we won't be
> > able to help you unless you provide us with those definitions. If you're
> > sure that one or more of those things is irrelevant, then remove the
> > thing that you think is irrelevant, and see if you can still reproduce
> > the problem. We need to see the definition of any item that you can't
> > remove.
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> On Tuesday, August 18, 2015 at 1:10:37 AM UTC+1, James Kuyper wrote:
> > On 08/17/2015 07:24 PM, janus wrote:
> > > Hello All,
> > > 
> > > I am not getting the expected result from the below code whenever I change '\0' to EOF. ... 
> > 
> > That's because you had incorrect expectations about what the result
> > would be. Was that a helpful response? If not, it's because you haven't
> > given us enough information to give you a more helpful response. You
> > should describe what inputs you used when you got unexpected results,
> > and what you expected the result to be, with an emphasis on the details
> > of how the expected result differed from the actual result.
> > 
> > > ... I noticed that the below will read pass the end of file. What is it that I am doing wrong? Could someone help me out?
> > 
> > The code you provided doesn't contain any calls to any routines that
> > involve files - nothing that opens them, reads them, writes them or
> > closes them. Therefore, it's not at all clear what the connection is
> > between your subject line, the above question, and this code. If your
> > problem does actually involve reading from a file, you need to show us
> > the part of your code that actually performs the read.
> > 
> > The code you provided relies upon the definition of the following
> > identifiers:
> > 	tokens
> > 	    type
> > 	    txt
> > 	    inttoken
> > 	tokenmem
> > 	addtokentolist
> > 	keytab
> > 	obplus
> > 	obminus
> > 	obneg
> > 	oband
> > 	eql
> > 	obtimes
> > 	obleq
> > 	oblss
> > 	obgeq
> > 	obgtr
> > 	obcolon
> > 	obsemicolon
> > 	period
> > 	rbrak
> > 	lbrak
> > 	lparen
> > 	rparen
> > 	obnot
> > 	obcomma
> > 	obnum
> > 	IdLen
> > 	kwlen
> > 	keytab
> > 	ident
> > 	hlist
> > 
> > The problem you're running into might depend upon an error in the
> > definition of one or more of those things - in which case we won't be
> > able to help you unless you provide us with those definitions. If you're
> > sure that one or more of those things is irrelevant, then remove the
> > thing that you think is irrelevant, and see if you can still reproduce
> > the problem. We need to see the definition of any item that you can't
> > remove.
> 
> I use the below to read the entire file. And the result is what is feed to 
> static tokens* tokenize(char* source) . However  because of the error I am getting I just decided to have something like this:
> 
> char* rdata = "the content of file"; //This is where I copied and pasted the content of my file. And because of this change, I changed EOF to '\0' in order to terminate a list of characters.  The code switch is virtually redundant to the issue at hand 
> static char *frd (const char *fn) {
> 
>   FILE *R;
>   char *contents;
>   size_t fsize;
>   size_t nrd;
>   size_t ttsize;
> 
>   R = fopen(fn, "r");
>   printf("Word Count: %d\n", meanSentenceLength(R));
>   if (!R) {
>     printf(fn);
>     printf("\n");
>     cerror(0, "Failed to open source file");
>   }
> 
>   /* Get  file's size */
>   fseek(R, 0, SEEK_END);
>   fsize = ftell(R);
>   fseek(R, 0, SEEK_SET);
>   ttsize = fsize;
>   fsize *= sizeof(char);
> 
>   printf("Size of bytes:: %d\n", ttsize);
> 
>   /* End marker*/
>   contents = (char*)malloc(fsize + 1);
>   cerror(contents, "Failed to create memory for array of characters");
> 
>   nrd = fread(contents, sizeof(char), 886, R);
>   cerror((void *)nrd, "Failed to read the source file");
>   contents[nrd] = '\0';
> 
>   if (fclose(R) == EOF) {
>     cerror(0, "Closing of source file failed");
> 
>   }
> 
>  // printf("%s\n", contents);
>   return contents;
> }


Thanks all for your support. The issue is not really what I painted, I just noticed that because I have first read the whole file into an array of characters  there is no need to treat the sentinel as EOF. The proper sentinel is '\0'. This just solved the problem and the logic is clear to me. 

Bart, Thanks for pointer out how to avoid playing with fire via ....

Regards, \Emeka

[toc] | [prev] | [next] | [standalone]


#67715

FromJames Kuyper <jameskuyper@verizon.net>
Date2015-08-18 10:18 -0400
Message-ID<mqvep1$ic6$1@dont-email.me>
In reply to#67681
On 08/18/2015 03:54 AM, janus wrote:
> On Tuesday, August 18, 2015 at 1:10:37 AM UTC+1, James Kuyper wrote:
>> On 08/17/2015 07:24 PM, janus wrote:
>>> Hello All,
>>>
>>> I am not getting the expected result from the below code whenever I change '\0' to EOF. ... 
>>
>> That's because you had incorrect expectations about what the result
>> would be. Was that a helpful response? If not, it's because you haven't
>> given us enough information to give you a more helpful response. You
>> should describe what inputs you used when you got unexpected results,
>> and what you expected the result to be, with an emphasis on the details
>> of how the expected result differed from the actual result.

You still haven't answered this question, which is the most important one.

>>> ... I noticed that the below will read pass the end of file. What is it that I am doing wrong? Could someone help me out?
>>
>> The code you provided doesn't contain any calls to any routines that
>> involve files - nothing that opens them, reads them, writes them or
>> closes them. Therefore, it's not at all clear what the connection is
>> between your subject line, the above question, and this code. If your
>> problem does actually involve reading from a file, you need to show us
>> the part of your code that actually performs the read.

At least you answered that question. Now, how is the code that you show
below connected to the code you presented in the first message?

>> The code you provided relies upon the definition of the following
>> identifiers:
[cut long list of identifiers]
...
>>
>> The problem you're running into might depend upon an error in the
>> definition of one or more of those things - in which case we won't be
>> able to help you unless you provide us with those definitions. If you're
>> sure that one or more of those things is irrelevant, then remove the
>> thing that you think is irrelevant, and see if you can still reproduce
>> the problem. We need to see the definition of any item that you can't
>> remove.

You haven't explained that, either.
...
> On Tuesday, August 18, 2015 at 1:10:37 AM UTC+1, James Kuyper wrote:
[A second complete copy of my message]
Why did you quote me twice?

> I use the below to read the entire file. And the result is what is feed to 
> static tokens* tokenize(char* source) . However  because of the error I am getting I just decided to have something like this:
> 
> char* rdata = "the content of file"; //This is where I copied and pasted the content of my file. And because of this change, I changed EOF to '\0' in order to terminate a list of characters.  The code switch is virtually redundant to the issue at hand 
> static char *frd (const char *fn) {
> 
>   FILE *R;
>   char *contents;
>   size_t fsize;
>   size_t nrd;
>   size_t ttsize;
> 
>   R = fopen(fn, "r");
>   printf("Word Count: %d\n", meanSentenceLength(R));
>   if (!R) {
>     printf(fn);
>     printf("\n");
>     cerror(0, "Failed to open source file");
>   }
> 
>   /* Get  file's size */
>   fseek(R, 0, SEEK_END);

Every I/O function can fail for reasons outside the control of your
program. Every I/O function returns a value that can be used to
determine whether or not it failed. You should always check the return
value, and take appropriate action if it does fail. What does
"appropriate action" mean? That's for you to define - but you should
give some thought to defining what you want your program to do if one of
the I/O functions fails.

>   fsize = ftell(R);

This combination of fseek() and ftell() will give you the file size for
some types of files on some systems, but not on others. That's because:

"For a text stream, its file position indicator contains unspecified
information, usable by the fseek function for returning the file
position indicator for the stream to its position at the time of the
ftell call; the difference between two such return values is not
necessarily a meaningful measure of the number of characters written
or read." (7.21.9.4p2)

Even on systems where it works on ordinary files, there may be special
kinds of files where it won't work.

>   fseek(R, 0, SEEK_SET);
>   ttsize = fsize;
>   fsize *= sizeof(char);

sizeof(char) is guaranteed by the standard to be 1. This is true even on
a system where char has more than 8 bits - on such a system, CHAR_BIT>8
but sizeof(char) is still 1.

>   printf("Size of bytes:: %d\n", ttsize);

English: "Size in bytes:".
ttsize has the type "size_t", which is necessarily an unsigned type,
that can store numbers as large as 65536 (7.20.3p2), but is otherwise
unspecified.
%d is for "int", a signed type. "int" could be a different size from
size_t. It might not be big enough to store the file size. Because of
this type mis-match, your code has undefined behavior.

If you're required to write C90 code, your best solution is:
    printf("Size in bytes:%lu\n", (unsigned long)ttsize);

If able to rely on the availability  of C99 or later, you can write:
    printf("Size in bytes:%zu\n", ttsize);

>   /* End marker*/
>   contents = (char*)malloc(fsize + 1);
>   cerror(contents, "Failed to create memory for array of characters");

I hope that cerror() call calls exit() if contents is a null pointer?
Otherwise, all of the following lines where 'contents" is referred to
could cause serious problems.

>   nrd = fread(contents, sizeof(char), 886, R);

Where did 806 come from? Why didn't you use fsize-1? If fsize was once
807, and is now different, that could produce all kinds of problems.

>   cerror((void *)nrd, "Failed to read the source file");

You're converting nrd, which could be any number from 0 to 806, to a
void*. Here's what the standard says about such conversions:

"Except as previously specified," (note: none of the previous
specifications is relevant) "the result is implementation-defined, might
not be correctly aligned, might not point to an entity of the referenced
type, and might be a trap representation." (6.3.2.3p5)

I suspect, based upon your prior uses of cerror(), that you're expecting
(void*)nrd to be a null pointer if nrd is 0, and otherwise be a
perfectly safe, if meaningless, pointer. Neither of those is guaranteed.
(void*)0 is a null pointer constant, which is guaranteed to be converted
to a null pointer of the appropriate type in many contexts. However, the
standard provides no special guarantees for (void*)nrd, even if nrd
happens to be 0. And if it is a trap representation. any use of that
value, even without dereferencing it, would render the behavior of your
program undefined.

>   contents[nrd] = '\0';
> 
>   if (fclose(R) == EOF) {
>     cerror(0, "Closing of source file failed");
> 
>   }
> 
>  // printf("%s\n", contents);
>   return contents;
> }
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#67733

FromBarry Schwarz <schwarzb@dqel.com>
Date2015-08-18 09:18 -0700
Message-ID<fem6ta10i0pa2abn5peflm0gergf5091fm@4ax.com>
In reply to#67681
On Tue, 18 Aug 2015 00:54:48 -0700 (PDT), janus <emekamicro@gmail.com>
wrote:

>  R = fopen(fn, "r");
>  printf("Word Count: %d\n", meanSentenceLength(R));
>  if (!R) {
>    printf(fn);
>    printf("\n");
>    cerror(0, "Failed to open source file");
>  }

Since other messages show that meanSentenceLength attempts to use R to
read a file, your if statement occurs too late.  If fn fails to open
for any reason, R will be set to NULL.  meanSentenceLength will then
cause undefined behavior by attempting to read from an invalid FILE*.
If you are going to test the result of a function for success (and you
definitely should in this case), then that test needs to occur before
you try to use the result to do some "real" processing.

-- 
Remove del for email

[toc] | [prev] | [next] | [standalone]


#67738

FromKeith Thompson <kst-u@mib.org>
Date2015-08-18 11:17 -0700
Message-ID<lnbne44g1k.fsf@kst-u.example.com>
In reply to#67733
Barry Schwarz <schwarzb@dqel.com> writes:
> On Tue, 18 Aug 2015 00:54:48 -0700 (PDT), janus <emekamicro@gmail.com>
> wrote:
>
>>  R = fopen(fn, "r");
>>  printf("Word Count: %d\n", meanSentenceLength(R));
>>  if (!R) {
>>    printf(fn);
>>    printf("\n");
>>    cerror(0, "Failed to open source file");
>>  }
>
> Since other messages show that meanSentenceLength attempts to use R to
> read a file, your if statement occurs too late.  If fn fails to open
> for any reason, R will be set to NULL.  meanSentenceLength will then
> cause undefined behavior by attempting to read from an invalid FILE*.
> If you are going to test the result of a function for success (and you
> definitely should in this case), then that test needs to occur before
> you try to use the result to do some "real" processing.

That's very likely true, but I don't think we've seen the implementation
of meanSentenceLength() (at least not in any direct parent of this
article), and it *might* handle a null pointer gracefully.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#67763

FromBarry Schwarz <schwarzb@dqel.com>
Date2015-08-18 13:24 -0700
Message-ID<9357taljdlqlcn4bi66m8f2g3orbuc74jb@4ax.com>
In reply to#67738
On Tue, 18 Aug 2015 11:17:43 -0700, Keith Thompson <kst-u@mib.org>
wrote:

>Barry Schwarz <schwarzb@dqel.com> writes:
>> On Tue, 18 Aug 2015 00:54:48 -0700 (PDT), janus <emekamicro@gmail.com>
>> wrote:
>>
>>>  R = fopen(fn, "r");
>>>  printf("Word Count: %d\n", meanSentenceLength(R));
>>>  if (!R) {
>>>    printf(fn);
>>>    printf("\n");
>>>    cerror(0, "Failed to open source file");
>>>  }
>>
>> Since other messages show that meanSentenceLength attempts to use R to
>> read a file, your if statement occurs too late.  If fn fails to open
>> for any reason, R will be set to NULL.  meanSentenceLength will then
>> cause undefined behavior by attempting to read from an invalid FILE*.
>> If you are going to test the result of a function for success (and you
>> definitely should in this case), then that test needs to occur before
>> you try to use the result to do some "real" processing.
>
>That's very likely true, but I don't think we've seen the implementation
>of meanSentenceLength() (at least not in any direct parent of this
>article), and it *might* handle a null pointer gracefully.

He showed the implementation in a thread with the subject "Ftell and
word count".

-- 
Remove del for email

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web