From owner-freebsd-questions@freebsd.org Thu May 14 21:02:43 2020 Return-Path: Delivered-To: freebsd-questions@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 6384B2DFBAB for ; Thu, 14 May 2020 21:02:43 +0000 (UTC) (envelope-from mail@ozzmosis.com) Received: from relay5-d.mail.gandi.net (relay5-d.mail.gandi.net [217.70.183.197]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 49NPBV1X6mz3wj1 for ; Thu, 14 May 2020 21:02:41 +0000 (UTC) (envelope-from mail@ozzmosis.com) X-Originating-IP: 167.179.139.56 Received: from blizzard.ozzmosis.com (167-179-139-56.a7b38b.mel.nbn.aussiebb.net [167.179.139.56]) (Authenticated sender: ozzmosis@ozzmosis.com) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 3B73F1C0002; Thu, 14 May 2020 21:02:39 +0000 (UTC) Received: by blizzard.ozzmosis.com (Postfix, from userid 1001) id D84B551981; Fri, 15 May 2020 07:02:33 +1000 (AEST) Date: Fri, 15 May 2020 07:02:33 +1000 From: andrew clarke To: Polytropon Cc: FreeBSD Questions Subject: Re: Multi-line text output via printf() et al. Message-ID: <20200514210233.sw6je2m3d6acnsib@ozzmosis.com> References: <20200514220904.7a4c1e28.freebsd@edvax.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200514220904.7a4c1e28.freebsd@edvax.de> User-Agent: NeoMutt/20200501 X-Rspamd-Queue-Id: 49NPBV1X6mz3wj1 X-Spamd-Bar: --- Authentication-Results: mx1.freebsd.org; dkim=none; dmarc=none; spf=pass (mx1.freebsd.org: domain of mail@ozzmosis.com designates 217.70.183.197 as permitted sender) smtp.mailfrom=mail@ozzmosis.com X-Spamd-Result: default: False [-3.55 / 15.00]; ARC_NA(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; HAS_XOIP(0.00)[]; FROM_HAS_DN(0.00)[]; R_SPF_ALLOW(-0.20)[+ip4:217.70.183.192/28]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; MIME_GOOD(-0.10)[text/plain]; MIME_TRACE(0.00)[0:+]; DMARC_NA(0.00)[ozzmosis.com]; TO_MATCH_ENVRCPT_SOME(0.00)[]; TO_DN_ALL(0.00)[]; RCPT_COUNT_TWO(0.00)[2]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; IP_SCORE(-1.15)[ip: (-2.89), ipnet: 217.70.176.0/20(-1.60), asn: 29169(-1.28), country: FR(-0.00)]; FROM_EQ_ENVFROM(0.00)[]; RCVD_IN_DNSWL_LOW(-0.10)[197.183.70.217.list.dnswl.org : 127.0.5.1]; R_DKIM_NA(0.00)[]; ASN(0.00)[asn:29169, ipnet:217.70.176.0/20, country:FR]; MID_RHS_MATCH_FROM(0.00)[]; RCVD_TLS_ALL(0.00)[]; RWL_MAILSPIKE_POSSIBLE(0.00)[197.183.70.217.rep.mailspike.net : 127.0.0.17] X-BeenThere: freebsd-questions@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: User questions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 May 2020 21:02:43 -0000 On 2020-05-14 22:09:04, Polytropon (freebsd@edvax.de) wrote: > c) multiple lines in one string: > > printf("This is the first line of text.\n > And this is the second line.\n > Finally a third line.\n"); You need to add a line continuation backslash for this to work: printf("This is the first line of text.\n \ And this is the second line.\n \ Finally a third line.\n"); > There is a specific restriction that if a string contains > conversion specifications for variables, those have to be > in the 1st argument, so printf() does not print several > strings as individual arguments except there's a first > one containing appropriate %s entries. This applies for > any string containing %: it has to be in the > first argument passed to printf(). > > d) multiple strings with format string: > > printf("%s%s%s", > "This is the first line of text.\n", > "And this is the second line.\n", > "Finally a third line.\n"); There is the risk your program will crash here if you supply the wrong number of arguments to printf(). It's easy to mess this up if you're not paying attention to the parameter count, and if the printf() happens to be an error message then the bug might not show up in production. Though linters built into modern versions of gcc and clang will usually catch problems like this and emit a warning. > In this case, the \n could be in the format string instead > of the text lines. > > So, what's the correct (or at least recommended way) of > doing this? Think about use cases like fprintf(stderr, ...) > for things like usage messages, or printing to a file for > multi-line entries. I don't think it matters too much as long as you're consistent. String internationalisation and localisation can complicate things though. This: printf( "This " "is " "a " "string.\n" ); is uncommon in C code I suspect because not many people know it's allowed by the preprocessor. In many (most?) other languages you need to explicitly concat the strings together.