Modified gets_ws() function

A

Andrew Poelstra

I've added the capability that if the input is quoted, it will read until the
end quote (ignoring whitespace and the stop character, which is its default
behavior).

gets_ws.c:
/* Reads from fh into buff (buff may be NULL, in which case characters *
* are discarded), up until it reaches either stop_c or whitespace. (In *
* the special case that the first character is a quote, it will simply *
* read everything until it reaches an end quote.) Unless buff is NULL, *
* it reads at most (maxlen-1) characters and null-terminates buff. If *
* count is non-NULL, it will be filled with the number of characters *
* read. Returns 0 on success or EOF on error. */
int gets_ws (char *buff, size_t *count, size_t maxlen, char stop_c, FILE *fh)
{
size_t i = 0;
int err = (fh == NULL);
int stop_white = 1;
int ch = getc (fh);

switch (ch)
{
case '\"':
case '\'':
case '`':
stop_white = 0;
stop_c = ch;
break;
case EOF:
err = 1;
}

while ((!stop_white || !isspace (ch)) &&
(!buff || i >= maxlen) &&
(ch != stop_c))
{
if (buff && i < maxlen)
buff[i++] = ch;

if (ch == EOF)
{
err = (ch == EOF);
ch = stop_c;
} else {
ch = getc (fh);
}
++i;
}

if (count != NULL)
*count = i;

ungetc (ch, fh);
return err ? EOF : 0;
}
 
A

Andrew Poelstra

I've added the capability that if the input is quoted, it will read until the
end quote (ignoring whitespace and the stop character, which is its default
behavior).

gets_ws.c:
/* Reads from fh into buff (buff may be NULL, in which case characters *
* are discarded), up until it reaches either stop_c or whitespace. (In *
* the special case that the first character is a quote, it will simply *
* read everything until it reaches an end quote.) Unless buff is NULL, *
* it reads at most (maxlen-1) characters and null-terminates buff. If *
* count is non-NULL, it will be filled with the number of characters *
* read. Returns 0 on success or EOF on error. */
int gets_ws (char *buff, size_t *count, size_t maxlen, char stop_c, FILE *fh)
{
size_t i = 0;
int err = (fh == NULL);
int stop_white = 1;
int ch = getc (fh);

switch (ch)
{
case '\"':
case '\'':
case '`':
stop_white = 0;
stop_c = ch;
break;
case EOF:
err = 1;
}

while ((!stop_white || !isspace (ch)) &&
(!buff || i >= maxlen) &&

This should be: (!buff || i < maxlen)
 
A

Andrew Poelstra

I've added the capability that if the input is quoted, it will read until the
end quote (ignoring whitespace and the stop character, which is its default
behavior).

gets_ws.c:
/* Reads from fh into buff (buff may be NULL, in which case characters *
* are discarded), up until it reaches either stop_c or whitespace. (In *
* the special case that the first character is a quote, it will simply *
* read everything until it reaches an end quote.) Unless buff is NULL, *
* it reads at most (maxlen-1) characters and null-terminates buff. If *
* count is non-NULL, it will be filled with the number of characters *
* read. Returns 0 on success or EOF on error. */
int gets_ws (char *buff, size_t *count, size_t maxlen, char stop_c, FILE *fh)
{
size_t i = 0;
int err = (fh == NULL);
int stop_white = 1;
int ch = getc (fh);

switch (ch)
{
case '\"':
case '\'':
case '`':
stop_white = 0;
stop_c = ch;
break;
case EOF:
err = 1;
}

while ((!stop_white || !isspace (ch)) &&
(!buff || i >= maxlen) &&
(ch != stop_c))
{
if (buff && i < maxlen)
buff[i++] = ch;

if (ch == EOF)
{
err = (ch == EOF);
ch = stop_c;
} else {
ch = getc (fh);
}
++i;
}

if (count != NULL)
*count = i;

And here I need to null-terminate:
/* We need to check in case maxlen is 0. */
if (buff && maxlen)
buff = 0;
 
B

Barry Schwarz

I've added the capability that if the input is quoted, it will read until the
end quote (ignoring whitespace and the stop character, which is its default
behavior).

gets_ws.c:
/* Reads from fh into buff (buff may be NULL, in which case characters *
* are discarded), up until it reaches either stop_c or whitespace. (In *
* the special case that the first character is a quote, it will simply *
* read everything until it reaches an end quote.) Unless buff is NULL, *
* it reads at most (maxlen-1) characters and null-terminates buff. If *
* count is non-NULL, it will be filled with the number of characters *
* read. Returns 0 on success or EOF on error. */
int gets_ws (char *buff, size_t *count, size_t maxlen, char stop_c, FILE *fh)
{
size_t i = 0;
int err = (fh == NULL);

You apparently have reason to be concerned about fh being NULL.
int stop_white = 1;
int ch = getc (fh);

If it is, this invokes undefined behavior.
switch (ch)
{
case '\"':
case '\'':
case '`':
stop_white = 0;
stop_c = ch;
break;
case EOF:
err = 1;
}

while ((!stop_white || !isspace (ch)) &&
(!buff || i >= maxlen) &&
(ch != stop_c))
{
if (buff && i < maxlen)
buff[i++] = ch;

if (ch == EOF)
{
err = (ch == EOF);
ch = stop_c;
} else {
ch = getc (fh);
}
++i;
}

if (count != NULL)
*count = i;

ungetc (ch, fh);
return err ? EOF : 0;
}


Remove del for email
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
474,184
Messages
2,570,979
Members
47,579
Latest member
CharaS3188

Latest Threads

Top