Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>There are quite a lot of regular expression packages, but yours seems to match the one in POSIX: <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/regcomp.html" rel="noreferrer"><code>regcomp()</code></a> etc.</p> <p>The two structures it defines in <code>&lt;regex.h&gt;</code> are:</p> <ul> <li><p><code>regex_t</code> containing at least <code>size_t re_nsub</code>, the number of parenthesized subexpressions.</p></li> <li><p><code>regmatch_t</code> containing at least <code>regoff_t rm_so</code>, the byte offset from start of string to start of substring, and <code>regoff_t rm_eo</code>, the byte offset from start of string of the first character after the end of substring.</p></li> </ul> <p>Note that 'offsets' are not pointers but indexes into the character array.</p> <p>The execution function is:</p> <ul> <li><code>int regexec(const regex_t *restrict preg, const char *restrict string, size_t nmatch, regmatch_t pmatch[restrict], int eflags);</code></li> </ul> <p>Your printing code should be:</p> <pre><code>for (int i = 0; i &lt; r.re_nsub; i++) { int start = m[i].rm_so; int finish = m[i].rm_eo; strcpy(matches[ind], ("%.*s\n", (finish - start), p + start)); printf("Storing: %.*s\n", (finish - start), matches[ind]); ind++; printf("%.*s\n", (finish - start), p + start); } </code></pre> <p>Note that this code should be upgraded to ensure that the string copy does not overflow the target string. It is also a good idea to mark the start and end of a string, for example like:</p> <pre><code> printf("&lt;&lt;%.*s&gt;&gt;\n", (finish - start), p + start); </code></pre> <p>This makes it a whole heap easier to see spaces etc.</p> <p><em>[In future, please attempt to provide an SSCCE (<a href="http://sscce.org/" rel="noreferrer">Short, Self-Contained, Correct Example</a>) so that people can help more easily.]</em></p> <p>This is an SSCCE that I created, probably in response to another SO question in 2010. It is one of a number of programs I keep that I call 'vignettes'; little programs that show the essence of some feature (such as POSIX regexes, in this case). I find them useful as memory joggers.</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;string.h&gt; #include &lt;errno.h&gt; #include &lt;regex.h&gt; #define tofind "^DAEMONS=\\(([^)]*)\\)[ \t]*$" int main(int argc, char **argv) { FILE *fp; char line[1024]; int retval = 0; regex_t re; regmatch_t rm[2]; //this file has this line "DAEMONS=(sysklogd network sshd !netfs !crond)" const char *filename = "/etc/rc.conf"; if (argc &gt; 1) filename = argv[1]; if (regcomp(&amp;re, tofind, REG_EXTENDED) != 0) { fprintf(stderr, "Failed to compile regex '%s'\n", tofind); return EXIT_FAILURE; } fp = fopen(filename, "r"); if (fp == 0) { fprintf(stderr, "Failed to open file %s (%d: %s)\n", filename, errno, strerror(errno)); return EXIT_FAILURE; } while ((fgets(line, 1024, fp)) != NULL) { line[strlen(line)-1] = '\0'; if ((retval = regexec(&amp;re, line, 2, rm, 0)) == 0) { printf("&lt;&lt;%s&gt;&gt;\n", line); printf("Line: &lt;&lt;%.*s&gt;&gt;\n", (int)(rm[0].rm_eo - rm[0].rm_so), line + rm[0].rm_so); printf("Text: &lt;&lt;%.*s&gt;&gt;\n", (int)(rm[1].rm_eo - rm[1].rm_so), line + rm[1].rm_so); char *src = line + rm[1].rm_so; char *end = line + rm[1].rm_eo; while (src &lt; end) { size_t len = strcspn(src, " "); if (src + len &gt; end) len = end - src; printf("Name: &lt;&lt;%.*s&gt;&gt;\n", (int)len, src); src += len; src += strspn(src, " "); } } } return EXIT_SUCCESS; } </code></pre> <p>This was designed to find a particular line starting <code>DAEMONS=</code> in a file <code>/etc/rc.conf</code>. You can adapt it to your purposes easily enough.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload