{"id":64247,"date":"2022-05-10T09:01:22","date_gmt":"2022-05-10T09:01:22","guid":{"rendered":"https:\/\/www.cryptocabaret.com\/?p=64247"},"modified":"2022-05-10T09:01:22","modified_gmt":"2022-05-10T09:01:22","slug":"how-to-safely-read-user-input-with-the-getline-function","status":"publish","type":"post","link":"https:\/\/www.cryptocabaret.com\/?p=64247","title":{"rendered":"How to (safely) read user input with the getline function"},"content":{"rendered":"<p><span class=\"field field--name-title field--type-string field--label-hidden\">How to (safely) read user input with the getline function<\/span><br \/>\n<span class=\"field field--name-uid field--type-entity-reference field--label-hidden\"><a title=\"View user profile.\" href=\"https:\/\/opensource.com\/users\/jim-hall\" class=\"username\">Jim Hall<\/a><\/span><br \/>\n<span class=\"field field--name-created field--type-created field--label-hidden\">Tue, 05\/10\/2022 &#8211; 03:00<\/span><\/p>\n<div data-drupal-selector=\"rate-node-69988\" class=\"rate-widget-thumbs-up\" title=\"Register or Login to like.\">\n<div class=\"rate-thumbs-up-btn-up vote-pending\"><a href=\"https:\/\/opensource.com\/user\/register\">Register<\/a> or <a href=\"https:\/\/opensource.com\/user\/login?current=\/rss.xml\">Login<\/a> to like<\/div>\n<div class=\"rate-score\"><a href=\"https:\/\/opensource.com\/user\/register\">Register<\/a> or <a href=\"https:\/\/opensource.com\/user\/login?current=\/rss.xml\">Login<\/a> to like<\/div>\n<\/div>\n<div class=\"clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item\">\n<p>Reading strings in C used to be a very dangerous thing to do. When reading input from the user, programmers might be tempted to use the <code>gets<\/code> function from the C Standard Library. The usage for <code>gets<\/code> is simple enough:<\/p>\n<p><code>char *gets(char *string);<\/code><\/p>\n<p>That is, <code>gets<\/code> reads data from standard input, and stores the result in a string variable. Using <code>gets<\/code> returns a pointer to the string, or the value NULL if nothing was read.<\/p>\n<p>As a simple example, we might ask the user a question and read the result into a string:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\"><span class=\"co0\">#include <stdio.h><\/stdio.h><\/span><br><span class=\"co0\">#include <string.h><\/string.h><\/span><br><br>\nint<br>\nmain<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><br><span class=\"br0\">{<\/span><br>\n\u00a0 char city<span class=\"br0\">[<\/span><span class=\"nu0\">10<\/span><span class=\"br0\">]<\/span>; \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 <span class=\"sy0\">\/\/<\/span> Such <span class=\"kw2\">as<\/span> <span class=\"st0\">\"Chicago\"<\/span><br><br>\n\u00a0 <span class=\"sy0\">\/\/<\/span> this is bad .. please don<span class=\"st_h\">'t use gets<br><br>\n\u00a0 puts(\"Where do you live?\");<br>\n\u00a0 gets(city);<br><br>\n\u00a0 printf(\" is length %ldn\", city, strlen(city));<br><br>\n\u00a0 return 0;<br>\n}<\/span><\/div><\/div><\/pre>\n<p>Entering a relatively short value with the above program works well enough:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\">Where <span class=\"kw1\">do<\/span> you live?<br>\nChicago<br><span class=\"sy0\">Chicago<span class=\"sy0\">&gt;<\/span> is length <span class=\"nu0\">7<\/span><\/span><\/div><\/div><\/pre>\n<\/p>\n<div class=\"embedded-resource-list callout-float-right\">\n<div class=\"field field--name-title field--type-string field--label-hidden field__item\">Programming and development<\/div>\n<div class=\"field field--name-links field--type-link field--label-hidden field__items\">\n<div class=\"field__item\"><a href=\"https:\/\/developers.redhat.com\/?intcmp=7016000000127cYAAQ\">Red Hat Developers Blog<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/downloads\/cheat-sheets?intcmp=7016000000127cYAAQ\">Programming cheat sheets<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/www.redhat.com\/en\/services\/training\/learning-subscription?intcmp=7016000000127cYAAQ\">Try for free: Red Hat Learning Subscription<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/opensource.com\/downloads\/bash-programming-guide?intcmp=7016000000127cYAAQ\">eBook: An introduction to programming with Bash<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/developers.redhat.com\/cheat-sheets\/bash-shell-cheat-sheet?intcmp=7016000000127cYAAQ\">Bash shell scripting cheat sheet<\/a><\/div>\n<div class=\"field__item\"><a href=\"https:\/\/developers.redhat.com\/e-books\/modernizing-enterprise-java?intcmp=7016000000127cYAAQ\">eBook: Modernizing Enterprise Java<\/a><\/div>\n<\/p><\/div>\n<\/p><\/div>\n<p>However, the <code>gets<\/code> function is very simple, and will naively read data until it thinks the user is finished. But <code>gets<\/code> doesn&#8217;t check that the string is long enough to hold the user&#8217;s input. Entering a very long value will cause <code>gets<\/code> to store more data than the string variable can hold, resulting in overwriting other parts of memory.<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\">Where <span class=\"kw1\">do<\/span> you live?<br>\nLlanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch<br><span class=\"sy0\">Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch<span class=\"sy0\">&gt;<\/span> is length <span class=\"nu0\">58<\/span><br>\nSegmentation fault <span class=\"br0\">(<\/span>core dumped<span class=\"br0\">)<\/span><\/span><\/div><\/div><\/pre>\n<p>At best, overwriting parts of memory simply breaks the program. At worst, this introduces a critical security bug where a bad user can insert arbitrary data into the computer&#8217;s memory via your program.<\/p>\n<p>That&#8217;s why the <code>gets<\/code> function is dangerous to use in a program. Using <code>gets<\/code>, you have no control over how much data your program attempts to read from the user. This often leads to buffer overflow.<\/p>\n<h1>The safer way<\/h1>\n<p>The <code>fgets<\/code> function has historically been the recommended way to read strings safely. This version of <code>gets<\/code> provides a safety check by only reading up to a certain number of characters, passed as a function argument:<\/p>\n<p><code>char *fgets(char *string, int size, FILE *stream);<\/code><\/p>\n<p>The <code>fgets<\/code> function reads from the file pointer, and stores data into a string variable, but only up to the length indicated by <code>size<\/code>. We can test this by updating our sample program to use <code>fgets<\/code> instead of <code>gets<\/code>:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\"><span class=\"co0\">#include <stdio.h><\/stdio.h><\/span><br><br><span class=\"co0\">#include <string.h><\/string.h><\/span><br><br>\nint<br><br>\nmain<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><br><br><span class=\"br0\">{<\/span><br><br>\nchar city<span class=\"br0\">[<\/span><span class=\"nu0\">10<\/span><span class=\"br0\">]<\/span>; <span class=\"sy0\">\/\/<\/span> Such <span class=\"kw2\">as<\/span> \u201cChicago\u201d<br><br><span class=\"sy0\">\/\/<\/span> fgets is better but not perfect<br><br>\nputs<span class=\"br0\">(<\/span>\u201cWhere <span class=\"kw1\">do<\/span> you live?\u201d<span class=\"br0\">)<\/span>;<br><br>\nfgets<span class=\"br0\">(<\/span>city, <span class=\"nu0\">10<\/span>, stdin<span class=\"br0\">)<\/span>;<br><br><span class=\"kw3\">printf<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\" is length %ld<span class=\"es1\">n<\/span>\"<\/span>, city, strlen<span class=\"br0\">(<\/span>city<span class=\"br0\">)<\/span><span class=\"br0\">)<\/span>;<br><br><span class=\"kw3\">return<\/span> <span class=\"nu0\">0<\/span>;<br><br><span class=\"br0\">}<\/span><\/div><\/div><\/pre>\n<p>If you compile and run this program, you can enter an arbitrarily long city name at the prompt. However, the program will only read enough data to fit into a string variable of <code>size<\/code>=10. And because C adds a null (\u2018\u0000&#8217;) character to the ends of strings, that means<code>fgets<\/code> will only read 9 characters into the string:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\">Where <span class=\"kw1\">do<\/span> you live?<br>\nMinneapolis<br><span class=\"sy0\">Minneapol<span class=\"sy0\">&gt;<\/span> is length <span class=\"nu0\">9<\/span><\/span><\/div><\/div><\/pre>\n<p>While this is certainly safer than using <code>fgets<\/code> to read user input, it does so at the cost of &#8220;cutting off&#8221; your user&#8217;s input if it is too long.<\/p>\n<h1>The new safe way<\/h1>\n<p>A more flexible solution to reading long data is to allow the string-reading function to allocate more memory to the string, if the user entered more data than the variable might hold. By resizing the string variable as necessary, the program always has enough room to store the user&#8217;s input.<\/p>\n<p>The <code>getline<\/code> function does exactly that. This function reads input from an input stream, such as the keyboard or a file, and stores the data in a string variable. But unlike <code>fgets<\/code> and <code>gets<\/code>, <code>getline<\/code> resizes the string with <code>realloc<\/code> to ensure there is enough memory to store the complete input.<\/p>\n<p><code>ssize_t getline(char **pstring, size_t *size, FILE *stream);<\/code><\/p>\n<p>The<code> getline<\/code> is actually a wrapper to a similar function called <code>getdelim<\/code> that reads data up to a special delimiter character. In this case, <code>getline<\/code> uses a newline (&#8216;n&#8217;) as the delimiter, because when reading user input either from the keyboard or from a file, lines of data are separated by a newline character.<\/p>\n<p>The result is a much safer method to read arbitrary data, one line at a time. To use <code>getline<\/code>, define a string pointer and set it to NULL to indicate no memory has been set aside yet. Also define a &#8220;string size&#8221; variable of type <code>size_t<\/code> and give it a zero value. When you call <code>getline<\/code>, you&#8217;ll use pointers to both the string and the string size variables, and indicate where to read data. For a sample program, we can read from the standard input:<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\"><span class=\"co0\">#include <stdio.h><\/stdio.h><\/span><br><span class=\"co0\">#include <stdlib.h><\/stdlib.h><\/span><br><span class=\"co0\">#include <string.h><\/string.h><\/span><br><br>\nint<br>\nmain<span class=\"br0\">(<\/span><span class=\"br0\">)<\/span><br><span class=\"br0\">{<\/span><br>\n\u00a0 char <span class=\"sy0\">*<\/span>string = NULL;<br>\n\u00a0 size_t <span class=\"kw2\">size<\/span> = <span class=\"nu0\">0<\/span>;<br>\n\u00a0 ssize_t chars_read;<br><br>\n\u00a0 <span class=\"sy0\">\/\/<\/span> <span class=\"kw3\">read<\/span> a long string with getline<br><br>\n\u00a0 puts<span class=\"br0\">(<\/span><span class=\"st0\">\"Enter a really long string:\"<\/span><span class=\"br0\">)<\/span>;<br><br>\n\u00a0 chars_read = getline<span class=\"br0\">(<\/span><span class=\"sy0\">&amp;<\/span>string, <span class=\"sy0\">&amp;<\/span><span class=\"kw2\">size<\/span>, stdin<span class=\"br0\">)<\/span>;<br>\n\u00a0 <span class=\"kw3\">printf<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\"getline returned %ld<span class=\"es1\">n<\/span>\"<\/span>, chars_read<span class=\"br0\">)<\/span>;<br><br>\n\u00a0 <span class=\"sy0\">\/\/<\/span> check <span class=\"kw1\">for<\/span> errors<br><br>\n\u00a0 <span class=\"kw1\">if<\/span> <span class=\"br0\">(<\/span>chars_read <span class=\"sy0\"> <span class=\"nu0\">0<\/span><span class=\"br0\">)<\/span> <span class=\"br0\">{<\/span><br>\n\u00a0 \u00a0 puts<span class=\"br0\">(<\/span><span class=\"st0\">\"couldn't read the input\"<\/span><span class=\"br0\">)<\/span>;<br>\n\u00a0 \u00a0 <span class=\"kw2\">free<\/span><span class=\"br0\">(<\/span>string<span class=\"br0\">)<\/span>;<br>\n\u00a0 \u00a0 <span class=\"kw3\">return<\/span> <span class=\"nu0\">1<\/span>;<br>\n\u00a0 <span class=\"br0\">}<\/span><br><br>\n\u00a0 <span class=\"sy0\">\/\/<\/span> print the string<br><br>\n\u00a0 <span class=\"kw3\">printf<\/span><span class=\"br0\">(<\/span><span class=\"st0\">\" is length %ld<span class=\"es1\">n<\/span>\"<\/span>, string, strlen<span class=\"br0\">(<\/span>string<span class=\"br0\">)<\/span><span class=\"br0\">)<\/span>;<br><br>\n\u00a0 <span class=\"sy0\">\/\/<\/span> <span class=\"kw2\">free<\/span> the memory used by string<br><br>\n\u00a0 <span class=\"kw2\">free<\/span><span class=\"br0\">(<\/span>string<span class=\"br0\">)<\/span>;<br><br>\n\u00a0 <span class=\"kw3\">return<\/span> <span class=\"nu0\">0<\/span>;<br><span class=\"br0\">}<\/span><\/span><\/div><\/div><\/pre>\n<p>As the <code>getline<\/code> reads data, it will automatically reallocate more memory for the string variable as needed. When the function has read all the data from one line, it updates the size of the string via the pointer, and returns the number of characters read, including the delimiter.<\/p>\n<pre>\n<div class=\"geshifilter\"><div class=\"bash geshifilter-bash\">\u200b<br>\nEnter a really long string:<br>\nSupercalifragilisticexpialidocious<br>\ngetline returned <span class=\"nu0\">35<\/span><br><span class=\"sy0\">Supercalifragilisticexpialidocious<br><span class=\"sy0\">&gt;<\/span> is length <span class=\"nu0\">35<\/span><br><br><br>\n\u200b<\/span><\/div><\/div><\/pre>\n<p>Note that the string includes the delimiter character. For <code>getline<\/code>, the delimiter is the newline, which is why the output has a line feed in there. If you don&#8217;t want the delimiter in your string value, you can use another function to change the delimiter to a null character in the string.<\/p>\n<p>With<code> getline<\/code>, programmers can safely avoid one of the common pitfalls of C programming. You can never tell what data your user might try to enter, which is why using <code>gets<\/code> is unsafe, and <code>fgets<\/code> is awkward. Instead, <code>getline<\/code> offers a more flexible way to read user data into your program without breaking the system.<\/p>\n<\/div>\n<div class=\"clearfix text-formatted field field--name-field-article-subhead field--type-text-long field--label-hidden field__item\">\n<p>Getline offers a more flexible way to read user data into your program without breaking the system.<\/p>\n<\/div>\n<div class=\"field field--name-field-lead-image field--type-entity-reference field--label-hidden field__item\">\n<article class=\"media media--type-image media--view-mode-caption\">\n<div class=\"field field--name-field-media-image field--type-image field--label-hidden field__item\">  <img decoding=\"async\" src=\"https:\/\/www.cryptocabaret.com\/wp-content\/uploads\/2022\/05\/lenovo-thinkpad-laptop-concentration-focus-windows-office-1.png\" width=\"799\" height=\"447\" alt=\"Business woman on laptop sitting in front of window\" title=\"Woman using laptop concentrating\" loading=\"lazy\"><\/div>\n<div class=\"field field--name-field-caption field--type-text-long field--label-hidden caption field__item\"><span class=\"caption__byline\">Image by: <\/span><\/p>\n<p>Image by Mapbox Uncharted ERG,\u00a0<a href=\"https:\/\/creativecommons.org\/licenses\/by\/3.0\/us\/\" rel=\"noreferrer nofollow noopener\" target=\"_blank\">CC-BY 3.0 US<\/a><\/p>\n<\/div>\n<\/article>\n<\/div>\n<div class=\"hidden field field--name-field-listicle-title field--type-string field--label-hidden field__item\">What to read next<\/div>\n<div class=\"field field--name-field-default-license field--type-list-string field--label-hidden field__item\"><a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/\"><br \/>\n        <img decoding=\"async\" alt=\"Creative Commons License\" src=\"https:\/\/www.cryptocabaret.com\/wp-content\/uploads\/2022\/05\/cc-by-sa--11.png\" title=\"This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.\"><\/a>This work is licensed under a Creative Commons Attribution-Share Alike 4.0 International License.<\/div>\n<section class=\"field field--name-field-comments field--type-comment field--label-hidden comment-wrapper\">\n<div class=\"comments__count\">\n<div class=\"login\"><a href=\"https:\/\/opensource.com\/user\/register?absolute=1\">Register<\/a> or <a href=\"https:\/\/opensource.com\/user\/login?current=\/rss.xml&amp;absolute=1\">Login<\/a> to post a comment.<\/div>\n<\/p><\/div>\n<\/section>\n<p class=\"wpematico_credit\"><small>Powered by <a href=\"http:\/\/www.wpematico.com\" target=\"_blank\" rel=\"noopener\">WPeMatico<\/a><\/small><\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to (safely) read user input with the getline function Jim Hall Tue, 05\/10\/2022 &#8211; 03:00 Register or Login to like Register or Login to like Reading strings in C used to be a very dangerous thing to do. When reading input from the user, programmers might be tempted to use the gets function from [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":64248,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[307],"tags":[],"class_list":["post-64247","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-open-source"],"_links":{"self":[{"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/posts\/64247","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=64247"}],"version-history":[{"count":0,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/posts\/64247\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=\/wp\/v2\/media\/64248"}],"wp:attachment":[{"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=64247"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=64247"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cryptocabaret.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=64247"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}