{"id":6078,"date":"2023-10-28T00:01:37","date_gmt":"2023-10-28T07:01:37","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=6078"},"modified":"2024-10-12T16:07:00","modified_gmt":"2024-10-12T23:07:00","slug":"plucking-out-a-random-word","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=6078","title":{"rendered":"Plucking Out a Random Word"},"content":{"rendered":"<p>It&#8217;s time for your computer to babble nonsensically. No alcohol is necessary. All you must do is pluck out a random word from the dictionary. Run the program several times and you have babbly nonsense: <code>subtotal spectacles lute's sushi's<\/code>. Brilliant! <em>*HIC*<\/em><br \/>\n<!--more--><br \/>\nFrom <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6070\">last week&#8217;s Lesson<\/a>, you recall that the dictionary file contains a host of words, all in alphabetical order and (let&#8217;s hope) spelled correctly. Each word is stored on a line by itself. For this Lesson, the task is to grab a random word from the file.<\/p>\n<p>I&#8217;ve worked with such random-grabbing programs before. On my Wambooli website, I have a <a href=\"https:\/\/www.wambooli.com\/fun\/zen\/\" rel=\"noopener\" target=\"_blank\">&#8220;Zen moment&#8221; page<\/a> that generates a random silly phrase each time the page is loaded or refreshed. It operates on the same principle as this week&#8217;s code: Obtain the number of lines in a file, generate a random value in that range, output the line number matching the value.<\/p>\n<p>My Zen moment page is coded in PHP. The phrases are stored in an array. A single PHP function returns the array size, from which the random number is generated and the matching phrase output. For the Linux\/Unix dictionary and C programming, you must read in the full file to count the number of words, generate a random number based on that value, then re-read the file to access the random word:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2023_10_28-Lesson.c\" rel=\"noopener\" target=\"_blank\">2023_10_28-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;time.h&gt;\r\n\r\n<span class=\"comments\">\/* this code assumes the following path is valid *\/<\/span>\r\n#define DICTIONARY \"\/usr\/share\/dict\/words\"\r\n#define SIZE 32\r\n\r\nint main()\r\n{\r\n    FILE *dict;\r\n    int wc,rw;\r\n    char word[SIZE],*r;\r\n\r\n    <span class=\"comments\">\/* open the dictionary *\/<\/span>\r\n    dict = fopen(DICTIONARY,\"r\");\r\n    if( dict==NULL )\r\n    {\r\n        fprintf(stderr,\"Unable to open %s\\n\",DICTIONARY);\r\n        exit(1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* read and tally the words *\/<\/span>\r\n    wc = 0;\r\n    while( !feof(dict) )\r\n    {\r\n        r = fgets(word,SIZE,dict);    <span class=\"comments\">\/* read a word *\/<\/span>\r\n        if( r==NULL )\r\n            break;\r\n        wc++;\r\n    }\r\n\r\n    <span class=\"comments\">\/* pluck out a random word *\/<\/span>\r\n    rewind(dict);\r\n    srand( (unsigned)time(NULL) );\r\n    rw = rand() % wc;\r\n    while(rw)\r\n    {\r\n        r = fgets(word,SIZE,dict);    <span class=\"comments\">\/* read a word *\/<\/span>\r\n        rw--;\r\n    }\r\n    printf(\"%s\",word);\r\n\r\n    <span class=\"comments\">\/* close *\/<\/span>\r\n    fclose(dict);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>This code borrows a lot from previous lessons: The dictionary is opened. All entries are read and counted. The count value, stored in variable <code>wc<\/code>, is used with the <em>rand()<\/em> function to generate a random value within the word count range: <code>rw = rand() % wc;<\/code><\/p>\n<p>Before the random number is seeded and generated, something important must happen:<\/p>\n<p><code>rewind(dict);<\/code><\/p>\n<p>This statement returns the file position indicator to the start of the file. Otherwise, at this point in the code, the full file has already been read. The position indicator is at the EOF. When this statement is absent, the full list isn&#8217;t read again and the existing contents of the <code>word[]<\/code> buffer are output (the last word in the dictionary). Yes, I made this mistake and it took me a while to understand what happened.<\/p>\n<p>The random value generated, <code>rw<\/code>, is used in a <em>while<\/em> loop to again read words from the dictionary. For each word read, <code>rw<\/code> is decremented. Eventually the value reaches zero and the given word, stored in the <code>word[]<\/code> array, is output.<\/p>\n<p>Here is a sample run:<\/p>\n<p><code>superabundances<\/code><\/p>\n<p>If you were to construct a random (and meaningless) sentence, just re-read the file several times. Each time, remember to use the <em>rewind()<\/em> function to reset the file position indicator!<\/p>\n<p>In <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6082\">next week&#8217;s Lesson<\/a> I continue to play with the dictionary file.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What use are all those words in the dictionary if you can&#8217;t pluck out a few random ones? <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6078\">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-6078","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\/6078","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=6078"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6078\/revisions"}],"predecessor-version":[{"id":6636,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6078\/revisions\/6636"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6078"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6078"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6078"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}