{"id":4813,"date":"2021-06-19T00:01:23","date_gmt":"2021-06-19T07:01:23","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=4813"},"modified":"2021-06-22T07:54:35","modified_gmt":"2021-06-22T14:54:35","slug":"more-gobbling-with-the-fnmatch-function","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=4813","title":{"rendered":"More Globbling with the <em>fnmatch()<\/em> Function"},"content":{"rendered":"<p>Globbing is the use of wildcards to match filenames, which is something <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4782\">I touched upon<\/a> a few Lessons ago. It lead me to the <em>glob()<\/em> function, which reads a pathname for matching files. Often mentioned along with the <em>glob()<\/em> function, is the <em>fnmatch()<\/em> function, which serves a similar purpose.<br \/>\n<!--more--><br \/>\nAs you might guess, the FN in <em>fnmatch()<\/em> stands for filename. It&#8217;s more of a text-searching function than a true file function; unlike <em>glob()<\/em>, the <em>fnmatch()<\/em> function doesn&#8217;t scour a pathname on a file system for existing files. Instead, it uses a glob pattern to search a string. Here is the <em>man<\/em> page format:<\/p>\n<p><code>int fnmatch(const char *pattern, const char *string, int flags);<\/code><\/p>\n<p>The <code><em>pattern<\/em><\/code> is a string that can contain shell wildcards, such as <code>*.c<\/code>.<\/p>\n<p>The <code><em>string<\/em><\/code> is the text to search.<\/p>\n<p>The <code><em>flags<\/em><\/code> argument includes a series of defined constants, logically OR&#8217;d, to control the function&#8217;s behavior. For example, you can search for backslashes as characters instead of escape sequences. The value zero is specified for no flags.<\/p>\n<p>The return value is zero if the pattern matches. Otherwise a non-zero value is returned upon error. The return value can also be compared with the <code>FNM_NOMATCH<\/code> defined constant to confirm that no match was found instead of a true error condition.<\/p>\n<p>Use of the <em>fnmatch()<\/em> function requires including the <code>fnmatch.h<\/code> header file.<\/p>\n<p>The following code demonstrates the <em>fnmatch()<\/em> function:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2021_06_19-Lesson.c\" rel=\"noopener\" target=\"_blank\">2021_06_19-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;fnmatch.h&gt;\r\n\r\nint main()\r\n{\r\n    char pattern[] = \"*.c\";\r\n    char string[] = \"hello.c\";\r\n    int r;\r\n\r\n    r = fnmatch(pattern,string,0);\r\n    if( r==0 )\r\n        printf(\"'%s' matches '%s'\\n\",\r\n                pattern,\r\n                string\r\n              );\r\n    else if( r==FNM_NOMATCH )\r\n        printf(\"'%s' does not match '%s'\\n\",\r\n                pattern,\r\n                string\r\n              );\r\n    else\r\n        fprintf(stderr,\"fnmatch() error\\n\");\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <code>fnmatch.h<\/code> header file is included at Line 2. The <em>fnmatch()<\/em> function is used at Line 10, with variables <code>pattern<\/code> and <code>string<\/code>, which are declared at Lines 6 and 7. No flags are set (zero is specified as the third argument). The return value is saved in <em>int<\/em> variable <code>r<\/code>.<\/p>\n<p>At Line 11, the return value is compared with zero, meaning a match was found. A <em>printf()<\/em> statement outputs the cheerful results.<\/p>\n<p>The <em>else if<\/em> statement at Line 16 checks for the <code>FNM_NOMATCH<\/code> defined constant in the return value. If so, the function didn&#8217;t error but no match was found. A sober message is output at Line 17 (split across Lines 17 through 20).<\/p>\n<p>The final <em>else<\/em> statement at Line 21 outputs an error condition.<\/p>\n<p>Here&#8217;s a sample run:<\/p>\n<p><code>'*.c' matches 'hello.c'<\/code><\/p>\n<p>If you modify Line 7 to read <code>char string[] = \"hello.txt\";<\/code>, then build and run, the output becomes:<\/p>\n<p><code>'*.c' does not match 'hello.txt'<\/code><\/p>\n<p>As I wrote earlier, no files are opened or scanned from any directory with this function; <em>fnmatch()<\/em> is purely a text-matching function, though the first argument uses shell wildcards (globbing) for matching purposes.<\/p>\n<p>I suppose you could use the <em>fnmatch()<\/em> function as a text-searching tool, such as if you wanted to search a string by using the <code>*<\/code> and <code>?<\/code> wildcards. This approach opens the door to coding regular expressions, which is a can of worms I may open in a future series of Lessons.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The <em>fnmatch()<\/em> function is more of a string searching function than a filename matching tool. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4813\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-4813","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4813","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4813"}],"version-history":[{"count":7,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4813\/revisions"}],"predecessor-version":[{"id":4849,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/4813\/revisions\/4849"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4813"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4813"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4813"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}