{"id":1389,"date":"2015-06-06T00:01:25","date_gmt":"2015-06-06T07:01:25","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=1389"},"modified":"2015-05-30T09:57:38","modified_gmt":"2015-05-30T16:57:38","slug":"the-joys-of-iteration","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=1389","title":{"rendered":"The Joys of Iteration"},"content":{"rendered":"<p>Suppose that you&#8217;re testing code and need to run a program six times in a row. You could keep repeating the program, running it multiple times, but why not write a utility that does the same thing? That would be a good and practical way to put the <em>system()<\/em> function to work.<br \/>\n<!--more--><br \/>\nThe other day, I was testing some code and needed to run the program dozens of times. The way most terminal users accomplish that task is to press the up arrow key to fetch the preceding command:<\/p>\n<p>Up-Enter. Up-Enter. Up-Enter. And so on.<\/p>\n<p>I have to do this chore often enough, so I wrote a command line utility to handle the task. I was going to call the utility <em>repeat<\/em>, and that makes a lot of sense, but the word <em>iterate<\/em> is more programmish, so the utility is named <code>iterate<\/code>.<\/p>\n<blockquote><p>I&#8217;ve not seen a repeat\/iterate command in any operating system. Generally speaking, you code the shell to repeat a command. The shell scripting command <em>for<\/em> is frequently used, which explains why operating systems don&#8217;t come with a repeat\/iterate command. That shouldn&#8217;t stop you from coding your own utility just to make it easier.<\/p><\/blockquote>\n<p>The format for my <em>iterate<\/em> utility is:<\/p>\n<p><code>iterate <em>n<\/em> <em>command<\/em>...<\/code><\/p>\n<p>The value <em>n<\/em> is required. It ranges from 1 to whatever and indicates how many times the command repeats.<\/p>\n<p><em>command<\/em> is the command to repeat, which need not be enclosed in double quotes. Because of that, and due to the way a C program handles command line arguments, the code must stitch together the command string from multiple command line arguments.<\/p>\n<p>To carry out the command, the code uses the <em>system()<\/em> function:<\/p>\n<pre class=\"screen\">\r\n<span class=\"comments\">\/*\r\n   Iterate - repeat a given command\r\n   Dan Gookin, May 19, 2015\r\n *\/<\/span>\r\n\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\n#define BUFSIZE 1024\r\n\r\nvoid usage(void)\r\n{\r\n    puts(\"Usage:\\n\");\r\n    puts(\"  iterate n command\\n\");\r\n    puts(\"n       - repeat count, must be specified.\");\r\n    puts(\"          Range is 1 to n, where `n' is some\");\r\n    puts(\"          really big number.\");\r\n    puts(\"command - program name or command. Need\");\r\n    puts(\"          not be enclosed in quotes.\");\r\n}\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    int repeat_count,buffer_size,x;\r\n    char *command_buffer;\r\n\r\n    <span class=\"comments\">\/* Confirm proper number of arguments *\/<\/span>\r\n    if( argc &lt;= 2)\r\n    {\r\n        usage();\r\n        return(1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* Obtain iteration value *\/<\/span>\r\n    repeat_count = atoi(argv[1]);\r\n    if( repeat_count &lt; 1)\r\n    {\r\n        usage();\r\n        return(1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* Allocate storage for command line *\/<\/span>\r\n    command_buffer = (char *)malloc( sizeof(char) * BUFSIZE);\r\n    if( command_buffer == NULL)\r\n    {\r\n        puts(\"iterate: Some kind of memory allocation error.\");\r\n        return(2);\r\n    }\r\n\r\n    <span class=\"comments\">\/* de-parse the command string *\/<\/span>\r\n    *command_buffer = '\\0';\r\n    buffer_size = 0;\r\n    for(x=2;x&lt;argc;x++)\r\n    {\r\n        strcat(command_buffer,argv[x]);\r\n        strcat(command_buffer,\" \");\r\n            <span class=\"comments\">\/* Track buffer size, plus trailing space *\/<\/span>\r\n        buffer_size += strlen(argv[x])+1;\r\n            <span class=\"comments\">\/* Check for  buffer overflow *\/<\/span>\r\n        if(buffer_size &gt; BUFSIZE)\r\n        {\r\n            puts(\"iterate: Buffer overflow.\");\r\n            return(2);\r\n        }\r\n    }\r\n        <span class=\"comments\">\/* Eliminate last trailing space *\/<\/span>\r\n    buffer_size--;\r\n    *(command_buffer+buffer_size) = '\\0';\r\n\r\n    <span class=\"comments\">\/* Execute command repeat_count times *\/<\/span>\r\n    for(x=0;x&lt;repeat_count;x++)\r\n        system(command_buffer);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>This code uses some of the command line parsing tricks covered in <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=1315\">earlier Lessons<\/a>. At least two arguments are required, which is tested for at Line 29. Further, the <em>n<\/em> argument must be greater than one, which is tested for at Line 37.<\/p>\n<p>The <em>command<\/em> passed to the code might be a single argument or it could be multiple items that need to be assembled. That concatenation takes place starting at Line 54. After the buffer is initialized (Line 52), the <em>strcat()<\/em> function (Line 56). moves command line arguments into the buffer one after the other. Each argument is appended by a space (Line 58). The buffer size is tracked to prevent overflow (Lines 59 and 61).<\/p>\n<p>After the command line string is assembled, the final trailing space is removed at Lines 68 and 69. This step isn&#8217;t really necessary, but I&#8217;m a neat-and-tidy person.<\/p>\n<p>The repeating action happens at Lines 72 and 73. The <em>system()<\/em> function passes the <code>command_buffer<\/code>&#8216;s text to the operating system <code>repeat_count<\/code> number of times.<\/p>\n<p>This code represents my first version of the <em>iterate<\/em> utility. For later versions I added an option to separate output by adding spaces or other characters, plus an option that injects a pause between each iteration. That option is necessary when using random number generation based on the system clock. Feel free to add those switches on your own.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A utility to repeat a command <em>n<\/em> times. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1389\">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-1389","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\/1389","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=1389"}],"version-history":[{"count":6,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1389\/revisions"}],"predecessor-version":[{"id":1413,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1389\/revisions\/1413"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1389"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1389"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1389"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}