{"id":5191,"date":"2024-06-13T07:00:00","date_gmt":"2024-06-13T07:00:00","guid":{"rendered":"http:\/\/localhost:10196\/?post_type=articles&#038;p=5191"},"modified":"2024-06-07T15:46:11","modified_gmt":"2024-06-07T15:46:11","slug":"learning-to-program-copy-files","status":"publish","type":"articles","link":"https:\/\/allthingsopen.org\/articles\/learning-to-program-copy-files","title":{"rendered":"Learning to program: 2 ways to copy files in C"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Whenever I introduce someone to programming, whether that&#8217;s in an article or in a &#8220;teach yourself&#8221; video, I like to use methods that are easy for a beginner to understand. But the way you <em>teach<\/em> programming isn&#8217;t always the way you&#8217;d <em>actually<\/em> implement it in real life. There are always trade-offs, like performance or security, to balance with &#8220;making it easy to learn.&#8221; But the first time you learn something, it helps to keep things simple and build up to the other stuff once you understand the basics.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">From simple to more complex examples<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For example, if I were teaching someone about how to write their own version of the <code class=\"\" data-line=\"\">cat<\/code> command in C, I would use obvious variable names and make the program as straightforward as possible. One simple implementation might look like this:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">#include &lt;stdio.h&gt;\n\nint main(int arg_count, char *arg_list[])\n{\n   int item;\n   FILE *text_file;\n   char letter;\n\n   for (item = 1; item &lt; arg_count; item = item + 1) {\n       text_file = fopen(arg_list[item], &quot;r&quot;);\n\n       if (text_file != NULL) {\n           do {\n               letter = fgetc(text_file);\n\n               if (letter != EOF) {\n                   putchar(letter);\n               }\n           } while (letter != EOF);\n\n           fclose(text_file);\n       }\n   }\n\n   return 0;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is a very simple version of <code class=\"\" data-line=\"\">cat<\/code> that reads a list of files from the command line, which are stored in the <code class=\"\" data-line=\"\">arg_list<\/code> array. The program opens each file using a <em>file pointer<\/em> called <code class=\"\" data-line=\"\">text_file<\/code> then reads the file one letter at a time using <code class=\"\" data-line=\"\">fgetc<\/code> and prints the letter using <code class=\"\" data-line=\"\">putchar<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But while this version is very easy to read, it&#8217;s also very monolithic; everything happens inside the <code class=\"\" data-line=\"\">main<\/code> program. That&#8217;s okay for a short program like this to teach the basics, but a better way to write the <code class=\"\" data-line=\"\">cat<\/code> program is to break out the &#8220;read a file and print its contents&#8221; part into a <em>function<\/em> that is a bit more flexible. For example, we could rewrite this <code class=\"\" data-line=\"\">cat<\/code> program like this:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">#include &lt;stdio.h&gt;\n\nvoid cat(FILE *in, FILE *out)\n{\n   int ch;\n\n   while ((ch = fgetc(in)) != EOF) {\n       fputc(ch, out);\n   }\n}\n\nint main(int argc, char **argv)\n{\n   int i;\n   FILE *pfile;\n\n   for (i = 1; i &lt; argc; i++) {\n       pfile = fopen(argv[i], &quot;r&quot;);\n\n       if (pfile) {\n           cat(pfile, stdout);\n           fclose(pfile);\n       }\n   }\n\n   return 0;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This puts the important stuff in a function called <code class=\"\" data-line=\"\">cat<\/code> that reads from a file pointer called <code class=\"\" data-line=\"\">in<\/code> and prints to a different file pointer called <code class=\"\" data-line=\"\">out<\/code>. When we call the <code class=\"\" data-line=\"\">cat<\/code> function, we can specify a different input and output. In this case, the <code class=\"\" data-line=\"\">main<\/code> program only uses <code class=\"\" data-line=\"\">stdout<\/code> or the <em>standard output<\/em> when calling the <code class=\"\" data-line=\"\">cat<\/code> function &#8211; but in theory, this way of writing the <code class=\"\" data-line=\"\">cat<\/code> function to write to a file pointer instead of using <code class=\"\" data-line=\"\">putchar<\/code> makes it more flexible in case we ever decide to write directly to a different file later on.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This other version of <code class=\"\" data-line=\"\">cat<\/code> also uses different variable names like <code class=\"\" data-line=\"\">i<\/code> and <code class=\"\" data-line=\"\">pfile<\/code>, which is more common for very short programs that don&#8217;t need very descriptive variable names. Experienced programmers typically use <code class=\"\" data-line=\"\">i<\/code> as a counter or <em>index<\/em> variable, and <code class=\"\" data-line=\"\">pfile<\/code> as a <em>pointer<\/em> to a <em>file<\/em>. Otherwise, the program remains the same as the first simple version of <code class=\"\" data-line=\"\">cat<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But reading and writing one letter at a time isn&#8217;t the best way to do it. On modern systems with very fast CPUs and solid state drives, you might not notice the difference, but the performance impact of reading one letter then printing one letter will become more noticeable on slower systems.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To make this run a bit faster on these slower systems, you might instead read part of the file into memory (called a <em>buffer<\/em>) then write that buffer to the output. This is still the same basic algorithm of &#8220;read something, then write something,&#8221; but it&#8217;s able to do more at once, so it&#8217;s much faster even on slow systems. For example, we might update the <code class=\"\" data-line=\"\">cat<\/code> function one more time to read a file into a buffer using <code class=\"\" data-line=\"\">fread<\/code>, then write it back out using <code class=\"\" data-line=\"\">fwrite<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">void cat(FILE *in, FILE *out)\n{\n   unsigned char buf[128];\n   size_t numread;\n\n   while (!feof(in)) {\n       numread = fread(buf, sizeof(unsigned char), 128, in);\n       fwrite(buf, sizeof(unsigned char), numread, out);\n   }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Since the core functionality is in the <code class=\"\" data-line=\"\">cat<\/code> function, we only need to update that part of the program; the <code class=\"\" data-line=\"\">main<\/code> program can stay the same. This function creates a <em>buffer<\/em> of 128 bytes; an <code class=\"\" data-line=\"\">unsigned char<\/code> is exactly one <em>byte<\/em> long. The <code class=\"\" data-line=\"\">while<\/code> loop continues until it reaches the end of the file. Within the loop, it reads a bunch of data (up to 128 bytes) into the buffer using <code class=\"\" data-line=\"\">fread<\/code>, and keeps track of how much it read using the <code class=\"\" data-line=\"\">numread<\/code> variable. Then it writes that data back out using <code class=\"\" data-line=\"\">fwrite<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is basically the same <code class=\"\" data-line=\"\">cat<\/code> program that we wrote above, but it runs much faster even on slow systems because it reads a bunch of data at once. That way, the operating system can just read some data without having to keep going back to the file to read one letter at a time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, I wouldn&#8217;t use the &#8220;buffer&#8221; version of the program to teach someone about programming\u2014at least, not right away. It&#8217;s more complicated and difficult to understand. Instead, I&#8217;d start with the &#8220;one letter&#8221; version, and move up to the &#8220;buffer&#8221; method once we&#8217;d learned the basics about programming. The trade-off here is &#8220;easy to learn&#8221; with &#8220;runs fast.&#8221;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Running on slow systems<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">It can be hard to imagine what I mean by a &#8220;slow&#8221; system. Today&#8217;s computers are very fast; my computer at home has a 4-core 8th Generation Intel Core i3-8100T running at 3.10 GHz, with NVMe M.2 storage, and my system is already a few years old. On a system that fast, reading and writing one letter at a time runs at basically the same speed as reading and writing a bunch of data at once using a buffer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But not every system is that fast. For example, what we recognize as the personal computing era started in the late 1970s with the Commodore PET, TRS-80, and Apple II computers. In 1981, IBM released the IBM Personal Computer 5150, which became the basis for &#8220;PC&#8221; computers built after that. My 2019 PC can trace its lineage back to the original 1981 IBM PC.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In 1981, IBM used a very simple operating system called DOS, the <em>Disk Operating System<\/em>, provided by Microsoft. And DOS is still around, as the open source <a href=\"https:\/\/www.freedos.org\/\">FreeDOS Project<\/a>. FreeDOS is a more modern version of DOS, but it&#8217;s still DOS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because DOS has certain assumptions about the hardware it&#8217;s running on, you aren&#8217;t likely to run DOS <em>directly<\/em> on very new computers. Instead, most people run FreeDOS in a <em>virtual machine<\/em> or a PC emulator of some kind. And that provides an excellent opportunity to demonstrate running a slow system, because we can artificially slow down a virtual machine.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For this demonstration, I&#8217;ll use the QEMU virtual machine. QEMU supports Linux KVM, or <em>kernel virtual machine<\/em>, which makes the &#8220;guest&#8221; operating system run at almost native speeds. Without KVM, the &#8220;guest&#8221; runs through software emulation, which is much slower. So we can simulate a much slower system by running QEMU without KVM support.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A program to copy files<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s write a simple FreeDOS program that reads data from one file and writes it to another file. This is basically the same as the Linux <code class=\"\" data-line=\"\">cp<\/code> command, or the <code class=\"\" data-line=\"\">COPY<\/code> command on DOS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As with the <code class=\"\" data-line=\"\">cat<\/code> sample program, one way to write this program is to break out the core behavior into a function called <code class=\"\" data-line=\"\">cpy<\/code> which reads from one file pointer and writes to another file pointer. In the simplest case, this function reads just one character at a time using <code class=\"\" data-line=\"\">fgetc<\/code> and writes each character one at a time with <code class=\"\" data-line=\"\">fputc<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">#include &lt;stdio.h&gt;\n\nvoid cpy(FILE *in, FILE *out)\n{\n   int ch;\n\n   while ((ch = fgetc(in)) != EOF) {\n       fputc(ch, out);\n   }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is the same as the <code class=\"\" data-line=\"\">cat<\/code> function we wrote above, and is easy to explain to a new programmer: the function reads a character, then writes that character, and again, until it reaches the end of the file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But while that&#8217;s easy to explain, it isn&#8217;t very fast to run. So a better way to write this function is to read a bunch of data at once, then write that to the output:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">#include &lt;stdio.h&gt;\n\n#define BUFSIZE 128\n\ntypedef unsigned char byte_t;\n\nvoid cpy(FILE *in, FILE *out)\n{\n   byte_t buf[BUFSIZE];\n   size_t numread, numwrite;\n\n   while (!feof(in)) {\n       numread = fread(buf, sizeof(byte_t), BUFSIZE, in);\n\n       if (numread &gt; 0) {\n           numwrite = fwrite(buf, sizeof(byte_t), numread, out);\n\n           if (numwrite != numread) {\n               fputs(&quot;mismatch!\\n&quot;, stderr);\n               return;\n           }\n       }\n   }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This uses a <code class=\"\" data-line=\"\">typedef<\/code> statement so we don&#8217;t need to keep typing <code class=\"\" data-line=\"\">unsigned char<\/code> everywhere, but it&#8217;s otherwise the same as the &#8220;buffer&#8221; version of the cat function from above. I&#8217;ve also added some extra features here, because we know we&#8217;ll be copying files, and it&#8217;s very important to know that things work along the way. For example, the function has a little extra code to detect if the amount of data it wrote differs from the amount of data it read, and aborts with an error message if that happens. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Because both of the functions take the same <em>function arguments<\/em>, we can write just one <code class=\"\" data-line=\"\">main<\/code> program that uses either version of <code class=\"\" data-line=\"\">cpy<\/code> function:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">#include &lt;stdio.h&gt;\n\nvoid cpy(FILE * in, FILE * out);\n\nint main(int argc, char **argv)\n{\n   FILE *src, *dest;\n\n   \/* check command line *\/\n\n   if (argc != 3) {\n       fprintf(stderr, &quot;usage: cpy src dest\\n&quot;);\n       return 1;\n   }\n\n   \/* open files *\/\n\n   src = fopen(argv[1], &quot;rb&quot;);\n   if (src == NULL) {\n       fprintf(stderr, &quot;cannot open %s for reading\\n&quot;, argv[1]);\n       return 2;\n   }\n\n   dest = fopen(argv[2], &quot;wb&quot;);\n   if (dest == NULL) {\n       fprintf(stderr, &quot;cannot open %s for writing\\n&quot;, argv[2]);\n       fclose(src);\n       return 3;\n   }\n\n   \/* copy *\/\n\n   cpy(src, dest);\n   fclose(src);\n   fclose(dest);\n\n   return 0;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s a longer <code class=\"\" data-line=\"\">main<\/code> program than the <code class=\"\" data-line=\"\">cat<\/code> program used, but it also includes some extra code to detect errors when opening files, or if the user didn&#8217;t provide the right number of options on the command line. The basic outline is:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open the input file as <code class=\"\" data-line=\"\">src<\/code><\/li>\n\n\n\n<li>Open the output file as <code class=\"\" data-line=\"\">dest<\/code><\/li>\n\n\n\n<li>Use the <code class=\"\" data-line=\"\">cpy<\/code> function to copy from <code class=\"\" data-line=\"\">src<\/code> to <code class=\"\" data-line=\"\">dest<\/code><\/li>\n\n\n\n<li>Close both files<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">If we save the &#8220;one character at a time&#8221; version of the <code class=\"\" data-line=\"\">cpy<\/code> function as <code class=\"\" data-line=\"\">cpy1.c<\/code> and the &#8220;buffer&#8221; version as <code class=\"\" data-line=\"\">cpybuf.c<\/code>, and the main program as <code class=\"\" data-line=\"\">cpy.c<\/code>, we can compile two separate programs. I&#8217;ll use the open source OpenWatcom C compiler, which we include in the FreeDOS distribution:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">wcl -q cpy1.c cpy.c\nwcl -q cpybuf.c cpy.c<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Testing on a slow system<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">With these two versions of the <code class=\"\" data-line=\"\">cpy<\/code> program, we can see how fast or slow these run on FreeDOS, when running QEMU with and without KVM support. To run this test more consistently, I wrote a DOS &#8220;batch&#8221; file to copy a 9 MB zip file, then use the <code class=\"\" data-line=\"\">COMP<\/code> command to compare the original zip file with the copy. This also uses <code class=\"\" data-line=\"\">RUNTIME<\/code> (which you can install from the FreeDOS distribution) to tell me how long it takes to run each command. My <code class=\"\" data-line=\"\">TEST.BAT<\/code> file looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">@ECHO off\n\nset SRC=C:\\TEMP\\FILE.ZIP\nset DEST=C:\\TEMP\\FILE.OUT\n\necho using CPY1 ..\nruntime CPY1 %SRC% %DEST%\nCOMP %SRC% %DEST%\n\necho using CPYBUF ..\nruntime CPYBUF %SRC% %DEST%\nCOMP %SRC% %DEST%<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On Linux, I started a new instance of FreeDOS running in QEMU, with KVM. Running <code class=\"\" data-line=\"\">TEST.BAT<\/code> gives this output:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">using CPY1 ..\nRun time was 29.615385 seconds\nFiles compare OK.\nusing CPYBUF ..\nRun time was 29.285714 seconds\nFiles compare OK.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">KVM is the Linux kernel&#8217;s virtual machine accelerator, and it does a great job of helping the &#8220;guest&#8221; operating system run really fast inside QEMU. In this case, copying a 9 MB file one character at a time (with <code class=\"\" data-line=\"\">cpy1<\/code>) and by using a buffer (with <code class=\"\" data-line=\"\">cpybuf<\/code>) both take about 29 seconds.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">But if I restart the virtual machine and don&#8217;t enable KVM support, then QEMU has to process all machine instructions through software. That slows down most operations. For this example, running QEMU without KVM is probably closer to running FreeDOS on real hardware from the late 1990s era. You can see it takes much longer to copy the 9 MB file with these settings:<\/p>\n\n\n\n<pre class=\"wp-block-prismatic-blocks\"><code class=\"\" data-line=\"\">using CPY1 ..\nRun time was 105.879121 seconds\nFiles compare OK.\nusing CPYBUF ..\nRun time was 23.846154 seconds\nFiles compare OK.<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Copying the file by reading a bunch of data at once (using a buffer) takes the same amount of time as before, about 24 seconds. But reading and writing files one character at a time is <em>much<\/em> slower on this system, about 105 seconds (that&#8217;s 1 minute, 45 seconds).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Teach simple methods first<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The simplest methods can be much easier for beginner programmers to learn, but the trade-off is these basic implementations aren&#8217;t always the best in the real world. But I still like to use the more simple methods when I teach programming. My approach to teaching programming is &#8220;learn the basics first&#8221; then &#8220;use that to learn the more complex stuff.&#8221; And I still think that&#8217;s the right approach. Just keep in mind that the simplest version isn&#8217;t always the best version, even though it does the same thing.<\/p>\n","protected":false},"template":"","class_list":["post-5191","articles","type-articles","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Learning to program: 2 ways to copy files in C | We Love Open Source &#8226; All Things Open<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/allthingsopen.org\/articles\/learning-to-program-copy-files\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Learning to program: 2 ways to copy files in C | We Love Open Source &#8226; All Things Open\" \/>\n<meta property=\"og:description\" content=\"Whenever I introduce someone to programming, whether that&#8217;s in an article or in a &#8220;teach yourself&#8221; video, I like to use methods that are easy for a beginner to understand.... Read More\" \/>\n<meta property=\"og:url\" content=\"https:\/\/allthingsopen.org\/articles\/learning-to-program-copy-files\" \/>\n<meta property=\"og:site_name\" content=\"All Things Open\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/facebook.com\/AllThingsOpen\" \/>\n<meta property=\"og:image\" content=\"https:\/\/allthingsopen.org\/wp-content\/uploads\/2024\/05\/pair-pears-program-e1716932126263.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1920\" \/>\n\t<meta property=\"og:image:height\" content=\"1081\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@AllThingsOpen\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/allthingsopen.org\\\/articles\\\/learning-to-program-copy-files\",\"url\":\"https:\\\/\\\/allthingsopen.org\\\/articles\\\/learning-to-program-copy-files\",\"name\":\"Learning to program: 2 ways to copy files in C | We Love Open Source &#8226; All Things Open\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/allthingsopen.org\\\/#website\"},\"datePublished\":\"2024-06-13T07:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/allthingsopen.org\\\/articles\\\/learning-to-program-copy-files#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/allthingsopen.org\\\/articles\\\/learning-to-program-copy-files\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/allthingsopen.org\\\/articles\\\/learning-to-program-copy-files#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/allthingsopen.org\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Articles\",\"item\":\"https:\\\/\\\/allthingsopen.org\\\/articles\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Learning to program: 2 ways to copy files in C\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/allthingsopen.org\\\/#website\",\"url\":\"https:\\\/\\\/allthingsopen.org\\\/\",\"name\":\"All Things Open\",\"description\":\"A universe of events and platforms focused on open source, open tech and the open web.\",\"publisher\":{\"@id\":\"https:\\\/\\\/allthingsopen.org\\\/#organization\"},\"alternateName\":\"ATO\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/allthingsopen.org\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/allthingsopen.org\\\/#organization\",\"name\":\"All Things Open\",\"url\":\"https:\\\/\\\/allthingsopen.org\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/allthingsopen.org\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"http:\\\/\\\/allthingsopen.org\\\/wp-content\\\/uploads\\\/2021\\\/10\\\/2022_ATO_Logo_Red_NoDate.svg\",\"contentUrl\":\"http:\\\/\\\/allthingsopen.org\\\/wp-content\\\/uploads\\\/2021\\\/10\\\/2022_ATO_Logo_Red_NoDate.svg\",\"width\":\"1024\",\"height\":\"1024\",\"caption\":\"All Things Open\"},\"image\":{\"@id\":\"https:\\\/\\\/allthingsopen.org\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/facebook.com\\\/AllThingsOpen\",\"https:\\\/\\\/x.com\\\/AllThingsOpen\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/all-things-open\\\/\",\"https:\\\/\\\/www.instagram.com\\\/allthingsopen\",\"https:\\\/\\\/www.youtube.com\\\/allthingsopen\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Learning to program: 2 ways to copy files in C | We Love Open Source &#8226; All Things Open","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/allthingsopen.org\/articles\/learning-to-program-copy-files","og_locale":"en_US","og_type":"article","og_title":"Learning to program: 2 ways to copy files in C | We Love Open Source &#8226; All Things Open","og_description":"Whenever I introduce someone to programming, whether that&#8217;s in an article or in a &#8220;teach yourself&#8221; video, I like to use methods that are easy for a beginner to understand.... Read More","og_url":"https:\/\/allthingsopen.org\/articles\/learning-to-program-copy-files","og_site_name":"All Things Open","article_publisher":"https:\/\/facebook.com\/AllThingsOpen","og_image":[{"width":1920,"height":1081,"url":"https:\/\/allthingsopen.org\/wp-content\/uploads\/2024\/05\/pair-pears-program-e1716932126263.jpg","type":"image\/jpeg"}],"twitter_card":"summary_large_image","twitter_site":"@AllThingsOpen","twitter_misc":{"Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/allthingsopen.org\/articles\/learning-to-program-copy-files","url":"https:\/\/allthingsopen.org\/articles\/learning-to-program-copy-files","name":"Learning to program: 2 ways to copy files in C | We Love Open Source &#8226; All Things Open","isPartOf":{"@id":"https:\/\/allthingsopen.org\/#website"},"datePublished":"2024-06-13T07:00:00+00:00","breadcrumb":{"@id":"https:\/\/allthingsopen.org\/articles\/learning-to-program-copy-files#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/allthingsopen.org\/articles\/learning-to-program-copy-files"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/allthingsopen.org\/articles\/learning-to-program-copy-files#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/allthingsopen.org\/"},{"@type":"ListItem","position":2,"name":"Articles","item":"https:\/\/allthingsopen.org\/articles"},{"@type":"ListItem","position":3,"name":"Learning to program: 2 ways to copy files in C"}]},{"@type":"WebSite","@id":"https:\/\/allthingsopen.org\/#website","url":"https:\/\/allthingsopen.org\/","name":"All Things Open","description":"A universe of events and platforms focused on open source, open tech and the open web.","publisher":{"@id":"https:\/\/allthingsopen.org\/#organization"},"alternateName":"ATO","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/allthingsopen.org\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/allthingsopen.org\/#organization","name":"All Things Open","url":"https:\/\/allthingsopen.org\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/allthingsopen.org\/#\/schema\/logo\/image\/","url":"http:\/\/allthingsopen.org\/wp-content\/uploads\/2021\/10\/2022_ATO_Logo_Red_NoDate.svg","contentUrl":"http:\/\/allthingsopen.org\/wp-content\/uploads\/2021\/10\/2022_ATO_Logo_Red_NoDate.svg","width":"1024","height":"1024","caption":"All Things Open"},"image":{"@id":"https:\/\/allthingsopen.org\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/facebook.com\/AllThingsOpen","https:\/\/x.com\/AllThingsOpen","https:\/\/www.linkedin.com\/company\/all-things-open\/","https:\/\/www.instagram.com\/allthingsopen","https:\/\/www.youtube.com\/allthingsopen"]}]}},"_links":{"self":[{"href":"https:\/\/allthingsopen.org\/wp-json\/wp\/v2\/articles\/5191","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/allthingsopen.org\/wp-json\/wp\/v2\/articles"}],"about":[{"href":"https:\/\/allthingsopen.org\/wp-json\/wp\/v2\/types\/articles"}],"wp:attachment":[{"href":"https:\/\/allthingsopen.org\/wp-json\/wp\/v2\/media?parent=5191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}