{"id":5817,"date":"2023-04-08T00:01:15","date_gmt":"2023-04-08T07:01:15","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=5817"},"modified":"2023-03-25T11:23:32","modified_gmt":"2023-03-25T18:23:32","slug":"counting-the-non-ascii-bytes-solution","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=5817","title":{"rendered":"Counting the Non-ASCII Bytes &#8211; Solution"},"content":{"rendered":"<p>Several items are noteworthy for <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5810\">this month&#8217;s Exercise<\/a> , with the biggie being how to detect a non-ASCII character. The secret involves a wee bit of type conversion.<br \/>\n<!--more--><br \/>\nFirst, you must know how to detect whether a command line option is present.<\/p>\n<p>Second, you must open the argument as a file and properly report when this operation fails.<\/p>\n<p>After the file is open, the third step is to read each character in the file, from first to <code>EOF<\/code>. Along the way, these characters are examined to determine which are outside of the ASCII range (from zero through 127) and tally that count.<\/p>\n<p>Here is my solution:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2023_04-Exercise.c\" rel=\"noopener\" target=\"_blank\">2023_04-Exercise.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n\r\nint main(int argc,char *argv[])\r\n{\r\n    FILE *fp;\r\n    int count,c;\r\n    char *file;\r\n\r\n    <span class=\"comments\">\/* check for filename argument *\/<\/span>\r\n    if( argc&lt;2 )\r\n    {\r\n        fprintf(stderr,\"Specify a filename\\n\");\r\n        exit(1);\r\n    }\r\n    <span class=\"comments\">\/* open the file *\/<\/span>\r\n    file = argv[1];        <span class=\"comments\">\/* shortcut *\/<\/span>\r\n    fp = fopen(file,\"r\");\r\n    if( fp==NULL )\r\n    {\r\n        fprintf(stderr,\"Can't open '%s'\\n\",file);\r\n        exit(1);\r\n    }\r\n    printf(\"Examining '%s'...\\n\",file);\r\n\r\n    <span class=\"comments\">\/* scan for and count non-ASCII characters *\/<\/span>\r\n    count = 0;\r\n    while(!feof(fp))\r\n    {\r\n        c = fgetc(fp);\r\n        if( c==EOF )\r\n            break;\r\n        if((unsigned char)c &gt; 127 )\r\n            count++;\r\n    }\r\n\r\n    <span class=\"comments\">\/* close file and output results *\/<\/span>\r\n    fclose(fp);\r\n    printf(\"%d non-ASCII characters found\\n\",\r\n            count,\r\n          );\r\n\r\n    return(0);\r\n}<\/pre>\n<p>If present, a filename argument brings the <code>argc<\/code> value to two. This condition is tested for at Line 11.<\/p>\n<p>Next, the argument stored in <code>argv[1]<\/code> is copied to <em>char<\/em> pointer <code>file<\/code> for convenience. The file is opened. If this operation fails, an error message is output. Otherwise text is output to alert the user that the file is being examined.<\/p>\n<p>The <em>while<\/em> loop reads characters from the file. Is uses the <em>feof()<\/em> function to halt once the end-of-file is encountered for <em>FILE<\/em> pointer <code>fp<\/code>. Within the loop, the <em>fgets()<\/em> function reads characters into <em>int<\/em> variable <code>c<\/code>. A test is made immediately for the <code>EOF<\/code>, which breaks the loop once encountered.<\/p>\n<p>The magic happens at Line 33, where the value of character <code>c<\/code> is tested. First, the integer value is typecast to an <em>unsigned char<\/em> data type. It must be <em>unsigned<\/em> or any values above 127 are interpreted as negative and the test never passes. The value must also be a <em>char<\/em> as <code>c<\/code> is declared as an <em>int<\/em>. If the character value is greater than 127, variable <code>count<\/code> is incremented.<\/p>\n<p>After the loop exits, meaning every byte of the file is read, the file is closed and a <em>printf()<\/em> statement outputs the results.<\/p>\n<p>The tricky part for this solution is the <em>unsigned char<\/em> typecast, which allows the ASCII test to pass or fail. I hope your solution met with success.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Several items are noteworthy for this month&#8217;s Exercise , with the biggie being how to detect a non-ASCII character. The secret involves a wee bit of type conversion.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-5817","post","type-post","status-publish","format-standard","hentry","category-solution"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5817","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=5817"}],"version-history":[{"count":2,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5817\/revisions"}],"predecessor-version":[{"id":5827,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5817\/revisions\/5827"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5817"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5817"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5817"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}