Link to home
Start Free TrialLog in
Avatar of Gary Kline
Gary Kline

asked on

How to translate this 2-line while loop into C from Perl?

while (<>)
{
s/(?<=\w)\s*--\s*(?=\w)/--/g; #No spaces around hyphens
print;
}

Open in new window

Avatar of Kim Ryan
Kim Ryan
Flag of Australia image

Standard C does not have built in support for regular expressions, you would need to rely on a library for this Also no equivalent of the <> operator. C code would be much more complex, just wondering if C is the best choice for this type of code?
Avatar of Gary Kline
Gary Kline

ASKER

Hope this work to repl to the above note!  No, no deadline.  Moreover, i had it working before my '09 Dell went south.   A brief comment on what Kim noted is that an earlier try used the C regex.h header.  The while(<>) of Perl is replaced by while (FILE *fp) as best I remember.  The function caught two hyphens, and voila, a DASH.  

I may be thinkinng of related C functions; they died with my disk, <bleep>.    I appreciate the assist, gents.

gary
Avatar of sarabande
I am taking the liberty of adding the homework zone to your question
i hope i am right that the question no longer is assumed to be homework.

perhaps you could adopt the following to your needs:

void remove_spaces_from_hyphens(char * sztxt)
{
     char * psz;
     int       len = strlen(sztxt);

     while (psz = strstr(sztxt, " --"))
     {
          memmove(psz, psz+1, --len-(psz-sztxt));
     } 

     while (psz = strstr(sztxt, "-- "))
     {
          memmove(psz+2, psz+3, --len-(psz+2-sztxt));
     } 
}

Open in new window


note, memmove would allow to have an overlap of buffers to copy.

if you could use c++ instead of ansi c you would use replace member function of a string class  

Sara
Thanks very much; thiss looks close to what I had before my drive crashed.  I spent hours reviewing the hundreds of small-to-medium program fragments that I've written since the late 1970's.  No luckk;  time for a nap1

FWIW, I have some programs--all src--on the FreeBSD site.  

gary
Saraa,  ths works; I finished it last Moday.   Omly main() od my code; the rest belons to Lars--from his publib.    Tried to avoid  it, but gave in...  
/*
 * This tiny test programs trims whitespace from a DASH ("--") as demonstrated in s0-s2.
 *  ompile: gcc -o dash dash.c
 */
#include <stdio.h>
#include <assert.h>
#include <ctype.h>
#include <string.h>

char *trim (char *s);
char *ltrim (char *s);
char *rtrim (char *s);

int
main ()
{
    char s0[16], s1[16], s2[16];
    strcpy(s0, "  --"); strcpy(s1, "--   "); strcpy(s2, "  --  "); /* Initialize all char arrays */
    printf ("Show strings: = [%s,%s,%s]\n\n\n", s0, s1, s2);

      {
          printf ("PRE trim for s0: = [%s]\n", s0);
          trim (s0);
          printf ("POST trim: = [%s]\n\n", s0);

          printf ("PRE trim for s1: = [%s]\n", s1);
          trim (s1);
          printf ("POST trim: = [%s]\n\n", s1);

          printf ("PRE trim for s2: = [%s]\n", s2);
          trim (s2);
          printf ("POST trim: = [%s]\n\n", s2);
      }
}
char *
ltrim (char *s)
{
    char *t;

    for (t = s; isspace (*t); ++t)
        continue;
    memmove (s, t, strlen (t) + 1);     /* +1 so that '\0' is moved too */
    return s;
}

char *
rtrim (char *s)
{
    char *t, *tt;

    for (tt = t = s; *t != '\0'; ++t)
        if (!isspace (*t))
            tt = t + 1;
    *tt = '\0';

    return s;
}

char *
trim (char *s)
{
    assert (s != NULL);
    rtrim (s);
    ltrim (s);
    return s;
}

Open in new window

My +1 to Sara's suggestion to learn/use the latest C++. It is much easier to write these days, than the more-lines/lower-level/more error prone C code. Moreover, the later C++ standard defines also the regex standard module. Then you can translate your Perl code to something like this:
#include <iostream>
#include <string>
#include <regex>
using namespace std;

int main()
{
    regex dash_with_spaces_rex{ R"(\b\s*--\s*\b)" }; // better to compile in advance
    string line;
    while (getline(cin, line)) {
        cout << regex_replace(line, dash_with_spaces_rex, "--") << "\n";
    }
    return 0;
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of sarabande
sarabande
Flag of Luxembourg image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial