Re: equivalent of chomp in perl



2006-11-03 <lnslh0kvgb.fsf@xxxxxxxxxxxxxxx>,
Keith Thompson wrote:
Jordan Abel <random@xxxxxxxxxxxxx> writes:
[...]
Anyway, in answer to the question

void
chomp(char *x) {
char *p = strrchr(x,'\n');
if(p) *p = 0;
}

Not quite.

Let's look at the definition from the Camel Book (the canonical book
on Perl, comparable to K&R). This is arguably a little off-topic, but
it's a good example of the pitfalls of emulating features of one
language in another language.

chomp VARIABLE
chomp LIST
chomp

This function (normally) deletes a trailing newline from the end
of a string contained in a variable. This is a slightly safer
version of chop (described next) in that it has no effect upon a
string that doesn't end in a newline. More specifically, it
deletes the terminating string corresponding to the current value
of $/, and not just any last character.

Unlike chop, chomp returns the number of characters deleted. If $/
is "" (in paragraph mode), chomp removes all trailing newlines
from the selected string (or strings, if chomping a LIST). You
cannot chomp a literal, only a variable.

Some of the features of chomp aren't applicable to a C version: it can
be applied to either a list or a single variable, and the argument
defaults to $_ (if you're not familiar with Perl, don't worry about
what that means). And C has no equivalent to $/ (which in Perl lets
you set the input record separator to something other than the default
"\n").

So a reasonable C chomp() would operate on a single string, would
remove the last character if and only if it's a '\n', and would return
1 if it removed a character and 0 if it didn't.

Jordan, your version clobbers the last '\n' in the string, even if
it's not at the end of the string.

Here's my attempt:

int chomp(char *s)
{
size_t len = strlen(s);
if (len == 0) {
return 0;
}
else if (s[len-1] == '\n') {
s[len-1] = '\0';
return 1;
}
else {
return 0;
}
}

I did mess up.

How about

chomp(s)
char *s;
{
if(s && *s) {
char *p = strrchr(s,0);
if(p[-1]=='\n') {
p[-1]=0;
return 1;
}
}
return 0;
}

may be slightly more efficient than yours if the compiler doesn't get
especially clever with strlen calls.

I threw in null pointer handling because it's practically free.

You could add an int INPUT_RECORD_SEPARATOR; variable, but for it to be
useful you'd need an fgets replacement.
.



Relevant Pages

  • Re: equivalent of chomp in perl
    ... on Perl, comparable to K&R). ... chomp VARIABLE ... string that doesn't end in a newline. ... char *s; ...
    (comp.lang.c)
  • Re: finding strings in a text file help
    ... digits and reserved words and then prints them out in order ... > it gets the whole string matches it against the reserved words array ... one character of a potential word in your "s" string. ... a char[] array would do. ...
    (comp.lang.java.help)
  • Re: detecting characters on RS232-Interface
    ... read data into string variable ... > splitted at the end of the receive buffer). ... examine the next char in turn. ... When a character ...
    (microsoft.public.vb.general.discussion)
  • Re: remove spaces from a string and Complexity
    ... string character by character and copying onto another output string. ... void delchar(char *s, char c) ... I've seen functions written as above, however I'm still a little confused about one point - C passes by value therefore with your above function wouldn't the following behave incorrectly (incorrectly as in not modify the contents referenced by the first parameter but instead modify a copy of it): ...
    (comp.lang.c)
  • Re: "Read stuff from a file and chop it up to do stuff" code advice wanted.
    ... ;; This function returns TRUE if any character ... (if (char< char #\!) ... a stream and an array to hold characters in temp memory. ... ;; resulting string. ...
    (comp.lang.lisp)