-2

I am trying to make a simple code sample, in which I can have a sub-string, into a new string.

My code is below:

char titulo[20];
char line[] = "PRINCIPAL,1.Liga,2.Clubes,3.Jogadores,4.Relatorios,5.Sair;";
char *pos = strchr(line,',');

memcpy(titulo, line,*pos);

The problem, is that when I do:

printf("%s",titulo);

I get something like:

PRINCIPAL,1.Liga,2.Clubes,3.Jogadores,4.Rela

Ahmed Akhtar
  • 1,444
  • 1
  • 16
  • 28
Rafael Botas
  • 125
  • 1
  • 1
  • 9
  • 3
    What do you think passing `*pos` to `memcpy` does? – David Schwartz Feb 04 '16 at 11:53
  • The memcpy takes a pointer to the source buffer as the second argument, and the size of the data to copy as the third argument. So you have passed wrong parameters. Most probably you should be warned by the compiller about this. – dmi Feb 04 '16 at 11:56
  • What is `titulo` ? What is `m`? And did you compile with all warnings enabled? – Jabberwocky Feb 04 '16 at 12:35
  • Sorry my code was pasted wrong I forgot somethings, but have corrected it already. – Rafael Botas Feb 04 '16 at 12:41
  • Isn't supposed to *pos retrieves me the index of the char , ? so the memcpy will retrieve me the PRINCIPAL string. – Rafael Botas Feb 04 '16 at 12:42
  • 2
    @RafaelBotas: `char * pos` makes `pos` a pointer to `char`. That makes `*pos`... a `char`. `memcpy()` will happily interpret the ASCII value of that `char` -- `0x2c` -- as the number of bytes to copy. That's the 44 characters you see in `titulo`... and since `titulo` only has *place* for 20 characters... you are *deep* in "undefined behavour" country. If you want the *index* of the `','` you were searching the string for, you need `pos - line`. – DevSolar Feb 04 '16 at 12:44
  • 1
    @RafaelBotas: And please, *do* check `pos` for `NULL` first, in case `strchr()` didn't find the character you were looking for. *And* check that `pos - line` fits into `titulo` *before* doing the copy. – DevSolar Feb 04 '16 at 12:50

1 Answers1

2

Because you need to null terminate titulo. Example

char line[] = "PRINCIPAL,1.Liga,2.Clubes,3.Jogadores,4.Relatorios,5.Sair;";
char *pointer = strchr(line, ',');
if (pointer != NULL)
{
    char *substr;
    size_t length;
    length = pointer - line;
    /* Perhaps check if `length == 0', but it doesn't matter
     * because you would end up with an empty but valid sub string
     * anyway.
     */
    substr = malloc(length + 1);
    if (substr != NULL)
    {
        memcpy(substr, line, length);
        substr[length] = '\0';
        /* Use `substr' here */
        printf("%s\n", substr);
        /* Don't forget to free */
        free(substr);
    }
}
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • Should be `length = pointer - line + 1;`, +1 because the array is zero-indexed. – Lundin Feb 04 '16 at 11:57
  • 1
    That would include the delimiter character, a check for `length == 0` would be better. – Iharob Al Asimi Feb 04 '16 at 11:58
  • Checked your answer because what I was missing was the pointer - line. like I'm doing it don't need to length+1. Can you tell me why do you use malloc? I've seen that reference when searching for answers but didn't realize what does It really make. – Rafael Botas Feb 04 '16 at 12:51
  • @RafaelBotas WARNING WARNING WARNING I don't think you don't need `length + 1`. If you are using `printf()` the sub strnig MUST BE *null* terminated. The `malloc()` function allocates memory dynamically, I can't explain what `malloc()` is in a comment you need to read about dynamic memory allocation in [tag:c]. – Iharob Al Asimi Feb 04 '16 at 13:02
  • Im not using the result to length the *substring so i dont need to use it with malloc or adding 1 to length. But as i want it dynamic i will use it like you wrote it. thanks for the help. Its the first time i use StackOverflow and i didn't just solve my problem but learned you it too. – Rafael Botas Feb 04 '16 at 13:20