Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #67655 > unrolled thread
| Started by | janus <emekamicro@gmail.com> |
|---|---|
| First post | 2015-08-17 16:24 -0700 |
| Last post | 2015-08-18 13:24 -0700 |
| Articles | 12 — 6 participants |
Back to article view | Back to comp.lang.c
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
| From | janus <emekamicro@gmail.com> |
|---|---|
| Date | 2015-08-17 16:24 -0700 |
| Subject | Reading 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]
| From | Bartc <bc@freeuk.com> |
|---|---|
| Date | 2015-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-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]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2015-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-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]
| From | janus <emekamicro@gmail.com> |
|---|---|
| Date | 2015-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]
| From | janus <emekamicro@gmail.com> |
|---|---|
| Date | 2015-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2015-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]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2015-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]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2015-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]
| From | Barry Schwarz <schwarzb@dqel.com> |
|---|---|
| Date | 2015-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