Re: Concat some string not ended...
Date: 04/01/05

Date: 31 Mar 2005 23:08:42 GMT

collinm <> 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 : '.' );


    free( ALL );
                                    Regards, Jens

  \   Jens Thoms Toerring  ___

Relevant Pages

  • Re: Fast string operations
    ... Looping: I thought looping over arrays in managed code was "slow" ... array handling and such. ... The problem with TrimHelper is that it always returns a new string instance. ... The customer perceives this as a memory leak. ...
  • Re: remove first line in a textbox (readonly)
    ... The array returned is necessarily a copy of the actual data; at best, the array needs to be created and initialized for each call to the getter, and it's entirely possible all of the string instances are created as well. ... magic of memory allocation work here, my old school c training tells ...
  • Re: Segmentation fault
    ... Here you ask for a pointer to char. ... to a random position in memory. ... There's nothing else than a string the user could enter;-) ... to the use of scanf(). ...
  • Re: array-size/malloc limit and strlen() failure
    ... test2.c:6: error: size of array `arrc' is too large ... in other cases, the total available memory might be ... that string is too long so that I can bail out on time? ...
  • Re: is there an alternative to strstr
    ... >> To exploit this fact, you need a different data format, a plain string is ... > Ok I have put the email ids in a sorted array. ... However you can use an array of char pointers and use ... int cmp(const void *v1, const void *v2); ...