Re: Concat some string not ended...

Jens.Toerring_at_physik.fu-berlin.de
Date: 04/01/05


Date: 31 Mar 2005 23:08:42 GMT

collinm <collinm@laboiteaprog.com> wrote:
> i try to concat some string not ended

It might be better to be a bit careful with the nomenclature, in C
only a char array ending with a '\0' character is normally called
a "string". What you're dealing here with are simple char arrays
(and that's why you can't use the normal string functions like
strcpy() and strcat() etc. but must resort to memcpy()).

> void analyzeFilename(char *filename, int size, char *led_line)
> {
> printf("led_line: %s\n",led_line);

You've got a potential problem here: unless you have a C99 compiler
(or a compiler that supports this as an extension) you can't have
executable statements before all variables are defined.

> char CMD_INIT[]={'\0', '\0', '\0', '\0', '\0', '\1', 'Z', '0', '0',
> '\2'};
> char CMD_TEXT_FILE_TYPE[]={'A'};
> char CMD_FILE_LABEL=filename[0]; //get the first character of filename
> char CMD_HOLD[]={'\142'};
> char CMD_TXT_GREEN[]={'\34','\62'};
> char CMD_END[]={'\04'};

> char ALL[sizeof(CMD_INIT) + sizeof(CMD_TEXT_FILE_TYPE) +
> sizeof(CMD_FILE_LABEL) + sizeof(CMD_HOLD) +
               sizeof(CMD_TXT_GREEN) + size + sizeof(CMD_END)];

And here you rely on another C99 feature, variable length arrays.
In "classical" C they don't exist and you would get an error since
'size' isn't compile-time constant and thus the length of the array
isn't already known at that moment. You would have to make 'ALL'
a char pointer and than allocate enough memory. BTW, you need
only parentheses around the "argument" of sizeof() when it's a
type, for variables you can leave them out.

> char *p=ALL;

> memcpy(p,CMD_INIT, sizeof(CMD_INIT));
> p += sizeof(CMD_INIT);
> memcpy (p, CMD_TEXT_FILE_TYPE, sizeof(CMD_TEXT_FILE_TYPE));
> p += sizeof(CMD_TEXT_FILE_TYPE);
> memcpy (p, &CMD_FILE_LABEL, sizeof(CMD_FILE_LABEL));
> p += sizeof(CMD_FILE_LABEL);
> memcpy (p, CMD_HOLD, sizeof(CMD_HOLD));
> p += sizeof(CMD_HOLD);
> memcpy (p, CMD_TXT_GREEN, sizeof(CMD_TXT_GREEN));
> p += sizeof(CMD_TXT_GREEN);
> memcpy (p, filename, sizeof(size));
> p += sizeof(size);

Are you sure that you want sizeof(size) here? To me it looks more like
you just want 'size', i.e. you want to copy 'size' chars from what
'filename' points to.

> memcpy (p, CMD_END, sizeof(CMD_END));
> p += sizeof(CMD_END);

> printf("msg complet: \n");
> printf("sizeof(ALL) : %d\n", sizeof(ALL));
> for(p = ALL; *p < sizeof(ALL); p++)

That's definitely not correct, you need

> for(p = ALL; p < ALL + sizeof(ALL); p++)

> {
> if(isprint((char)*p))

The cast is complete superfluous, what 'p' points to is already a char.
If you want to become overly pedantic you should cast it to an int since
that's what isprint() expects.

> putchar(*p);
> else
> putchar('.');
> }
> putchar('\n');
> }

Here's a version of your function that hopefully does what you expect.
I avoided using C99 constructs, that's why I use malloc() to get enough
memory for the 'ALL' array. Of course, that has the drawback that there
is a (rather unlikely) chance of failure (but that could as well happen
with a variable length array and memory on the stack, where the VLA would
most likely end up is usually more scare than heap memory) and that you
have to deallocate the memory later on.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

void analyzeFilename( char *filename, int size, char *led_line )
{
    char CMD_INIT[ ] = { '\0', '\0', '\0', '\0', '\0',
                                   '\1', 'Z', '0', '0', '\2' };
    char CMD_TEXT_FILE_TYPE[ ] = { 'A' };
    char CMD_FILE_LABEL = filename[ 0 ];
    char CMD_HOLD[ ] = { '\142' };
    char CMD_TXT_GREEN[ ] = {'\34', '\62' };
    char CMD_END[ ] = {'\04' };
    char *ALL, *p;
    size_t len = sizeof CMD_INIT + sizeof CMD_TEXT_FILE_TYPE +
                 sizeof CMD_FILE_LABEL + sizeof CMD_HOLD +
                 sizeof CMD_TXT_GREEN + size + sizeof CMD_END;

    printf("led_line: %s\n",led_line);

    if ( ( ALL = p = malloc( len ) ) == NULL )
        exit( EXIT_FAILURE );

    memcpy( p, CMD_INIT, sizeof CMD_INIT );
    p += sizeof CMD_INIT;

    memcpy( p, CMD_TEXT_FILE_TYPE, sizeof CMD_TEXT_FILE_TYPE );
    p += sizeof CMD_TEXT_FILE_TYPE;

    *p++ = CMD_FILE_LABEL;

    memcpy ( p, CMD_HOLD, sizeof CMD_HOLD );
    p += sizeof CMD_HOLD ;

    memcpy( p, CMD_TXT_GREEN, sizeof CMD_TXT_GREEN );
    p += sizeof CMD_TXT_GREEN;

    memcpy( p, filename, size );
    p += size;
 
    memcpy( p, CMD_END, sizeof CMD_END );

    for ( p = ALL; p < ALL + len; p++ )
        putchar( isprint( *p ) ? *p : '.' );

    putchar('\n');

    free( ALL );
}
                                    Regards, Jens

-- 
  \   Jens Thoms Toerring  ___  Jens.Toerring@physik.fu-berlin.de
   \__________________________  http://www.toerring.de