Red Antigua Logo
Yet another piece of web.
Ads by Goooooogle
Search this site (by Google)
Tools    (top)
Your IP
Check a site for broken links
(W3C)

Perl modules    (top)
Tree::Numbered::Tools
(CPAN)
Perl tutorials    (top)
Perl modules
HTML::Template
CGI::Application
Mail::POP3Client
Mail::Send
MIME::Tools
Cookies with CGI::Application
Upload files with CGI::Application
Download files with CGI::Application
Redirect with CGI::Application
CPAN shell
Install DBD::mysql from the CPAN shell
Perl trim function
Validate an IP with Perl
Run suid Perl scripts under Apache
Perl taint mode
Perl date functions with Date::Calc

In Spanish
Curso de Perl

C tutorials    (top)
C - Introduction
C - Absolute beginner's Emacs
C - Examples for beginners
C - Makefile examples
C - Autotools examples
Server configurations    (top)
DNS
Apache
Apache Authentication and Access Control
mod_perl on FreeBSD
MySQL
MySQL add account
phpMyAdmin
Squid
DHCP

UNIX on Windows    (top)
Apache setup on Windows
MySQL setup on Windows
PHP setup on Windows
Perl setup on Windows
Emacs setup on Windows
UnxUtils
PuTTY
WinSCP
GIMP on Windows
MinGW - gcc on Windows
MSYS - UNIX-styled shell on Windows
msysDTK - autotools on Windows
GDB for MinGW on Windows

Misc. FreeBSD/UNIX    (top)
CD and DVD creation on FreeBSD using 'k3b' on FreeBSD
'portupgrade' on FreeBSD
'ipf' on FreeBSD
'pf' on FreeBSD
'su' on FreeBSD
Mount an ISO image under FreeBSD
Load the correct sound driver under FreeBSD without knowing what sound card you are using
Simultaneous sound channels on FreeBSD
FreeBSD network stuff
DOS-to-UNIX file conversion
favicon.ico on UNIX
Emacs tips
Sendmail tips
GKrellm
Command Line Calculator
Save multimedia streams with 'mplayer'
xargs - solution to 'Argument list too long'
Process multiple images from the command line using 'ImageMagick'
Turn the system bell off under X Windows
Process each line in an input file from the command line (or in a shell script)
How to keep a program running in the background using 'nohup'
How to remove symbolic links in the current directory using 'find' and 'rm'
How to remove Emacs backup files in the current directory and all subdirectories using 'find' and 'rm'
How to execute .profile without logging in
Configure X to handle non-English characters
How to move /var to /usr/var

Redirect a web page    (top)
Redirect to another web page
Apache redirect
C redirect
Perl redirect
PHP redirect
HTML redirect
JavaScript redirect

Javascript    (top)
Trim function
Login form
Register form
Popup window

Virus list    (top)
Latest 10 viruses - Sophos

Off topic    (top)
Personal home links

C - concat-strings-asprintf.c
C - concat-strings-asprintf.c
IndexPreviousNext
As the previous strcat/strncat/strlcat examples show, C can be very clumsy when it comes to concatening strings (or any kind of string manipulation, actually).
Using asprintf(3) is another, more convenient solution which is considered secure, and automatically allocates as much memory as you need.
The only thing you have to care about is to free the used memory when finished.
The drawback is that asprintf(3) isn't available on all platforms.
The source code below includes its own version of asprintf() if it can't be found in the system library (i.e. in stdio.h) on your operating system.

Tip: If you are new to pointers and memory allocation, you may want to read a pointer tutorial and a memory allocation tutorial.
You may also read the malloc(3)/free(3) man page.

concat-strings-asprintf.c:
/* Include unistd.h if not on MS Windows. */
#ifndef _WIN32
#include <unistd.h>
#endif

#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "asprintf.c"

/* Compile: cc -g -ansi -pedantic -Wall -O2 -o concat-strings-asprintf concat-strings-asprintf.c */
/* Run: ./concat-strings-asprintf */

int
main(int argc, char *argv[])
{
    char **pointer_to_full_name = NULL;
    char *full_name = NULL;
    int number_of_chars_printed = 0;
    
    /* Command line argument check. */
    if (argc != 3)
    {
        printf("Usage: %s <first_name> <last_name>\n", argv[0]);
        return 1;
    }
    /* Allocate enough memory for pointer-to-pointer to hold a pointer to char.  */
    if ((pointer_to_full_name = (char **)malloc(sizeof(pointer_to_full_name))) == NULL)
    {
        printf("malloc() error: %s\n", strerror(errno));
        return -1;
    }
    /* Good practice: always initialize *pointer_to_full_name. */
    *pointer_to_full_name = "\0";
    /* Concat strings using asprintf(). */
    if ((number_of_chars_printed = asprintf(pointer_to_full_name, "%s %s", argv[1], argv[2])) < 0)
    {
        printf("asprintf() error: %s\n", strerror(errno));
        free(pointer_to_full_name);
        return -1;
    }
    full_name = *pointer_to_full_name;
    printf("Your name is '%s'.\n", full_name);
    /* free() allocated memory. */
    free(full_name);
    free(pointer_to_full_name);

    return 0;
}

Copy the file below to the same directory as the file above, and it will be included if not present on your operating system.

asprintf.c:
/*
 * Copyright (c) 2004 Darren Tucker.
 *
 * Based originally on asprintf.c from OpenBSD:
 * Copyright (c) 1997 Todd C. Miller <Todd.Miller AT courtesan.com>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

extern int vsnprintf();

/* Include vasprintf() if not on your OS. */
#ifndef HAVE_VASPRINTF

#include <errno.h>
#include <limits.h>
#include <stdarg.h>
#include <stdlib.h>

#ifndef VA_COPY
# ifdef HAVE_VA_COPY
#  define VA_COPY(dest, src) va_copy(dest, src)
# else
#  ifdef HAVE___VA_COPY
#   define VA_COPY(dest, src) __va_copy(dest, src)
#  else
#   define VA_COPY(dest, src) (dest) = (src)
#  endif
# endif
#endif

#define INIT_SZ 128

int
vasprintf(char **str, const char *fmt, va_list ap)
{
        int ret = -1;
        va_list ap2;
        char *string, *newstr;
        size_t len;

        VA_COPY(ap2, ap);
        if ((string = malloc(INIT_SZ)) == NULL)
                goto fail;

        ret = vsnprintf(string, INIT_SZ, fmt, ap2);
        if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */
                *str = string;
        } else if (ret == INT_MAX || ret < 0) { /* Bad length */
                goto fail;
        } else {        /* bigger than initial, realloc allowing for nul */
                len = (size_t)ret + 1;
                if ((newstr = realloc(string, len)) == NULL) {
                        free(string);
                        goto fail;
                } else {
                        va_end(ap2);
                        VA_COPY(ap2, ap);
                        ret = vsnprintf(newstr, len, fmt, ap2);
                        if (ret >= 0 && (size_t)ret < len) {
                                *str = newstr;
                        } else { /* failed with realloc'ed string, give up */
                                free(newstr);
                                goto fail;
                        }
                }
        }
        va_end(ap2);
        return (ret);

fail:
        *str = NULL;
        errno = ENOMEM;
        va_end(ap2);
        return (-1);
}
#endif

/* Include asprintf() if not on your OS. */
#ifndef HAVE_ASPRINTF
int asprintf(char **str, const char *fmt, ...)
{
        va_list ap;
        int ret;
        
        *str = NULL;
        va_start(ap, fmt);
        ret = vasprintf(str, fmt, ap);
        va_end(ap);

        return ret;
}
#endif
IndexPreviousNext
Last modified: Tue Dec 18 12:55:06 Romance Standard Time 2007