Управление указателями с помощью C - PullRequest
2 голосов
/ 29 октября 2010

Работая с указателями в C, я получил очень незаметный результат, я работаю с токеном, который представляет собой строку байтов, которая мне нужна для создания пути к каталогу.токен состоит из даты в качестве префикса в формате 20101129 (2010-oct-29), а затем следует строка длиной 20 байт, таким образом токен будет выглядеть как 20101102A2D8B328CX9RDTBDE373, метод должен возвращать путь, который выглядит как 2010/11/02/A2D8/B328/CX9R/DTBD/E373.

Теперь с помощью метода, который я использовал в приведенном ниже коде, возвращаются строки с нежелательными символами, в то время как код выглядит нормально, код приведен ниже

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

#define token "20101102A2D8B328CX9RDTBDE373"
#define SLASH "/"

int main()
{
    char *mainstring = (char*)malloc(strlen(token));
    char *nextstring = (char*)malloc(strlen(token));
    char tokenarr[50] = token;
    char patharr[50];
    char pathmem[50];
    char *fullstring = (char*)malloc(strlen(token));

    char yrstr[4]="";
    char yrmem[4]="";
    char yrarr[4]="";

    char monstr[2]="";
    char monmem[2]="";
    char monarr[2]="";

    char daystr[2]="";
    char daymem[2]="";
    char dayarr[2]="";

    memcpy(mainstring,token,strlen(token));


    memcpy(yrarr,tokenarr,4);
    strncpy(yrstr,mainstring,4);
    memcpy(yrmem,mainstring,4);

    puts(yrarr);
    puts(yrstr);
    puts(yrmem);


    mainstring = mainstring +4;
    memcpy(monarr,tokenarr+4,2);
    strncpy(monstr,mainstring,2); 
    memcpy(monmem,mainstring,2);

    puts(monarr);    
    puts(monstr); 
    puts(monmem);    

    mainstring = mainstring+2;
    memcpy(dayarr,tokenarr+6,2);
    strncpy(daystr,mainstring,2);
    memcpy(daymem, mainstring,2);

    puts(dayarr);
    puts(daystr);
    puts(daymem);

    strcat(patharr,yrarr); strcat(pathmem,yrmem);
    strcat(patharr,"/"); strcat(pathmem,SLASH);
    strcat(patharr,monarr);strcat(pathmem,monmem);
    strcat(patharr,"/"); strcat(pathmem,SLASH);
    strcat(patharr,dayarr); strcat(pathmem,daymem);

    puts(patharr);
    puts(pathmem);

    mainstring = mainstring +2;
    int i;

    for(i=0;i<5;i++)
    {
        memcpy(nextstring,mainstring,4);
        mainstring = mainstring +4;
        printf("The %d th string is:",i+1);        
        puts(nextstring); strcat(fullstring,"/");
        strcat(fullstring, nextstring);

        puts(fullstring);
    }
    strcat(patharr,fullstring); 
    strcat(pathmem,fullstring);
    puts(patharr);
    puts(pathmem);


return 0;

}

Результаты из кода:

2010
2010
2010
11
11m��
11
02m
02
02
2010/11 / 02m
��m�� 2010/11/02
1-я строка: A2D8
/ A2D8
2-я строка: B328
/ A2D8 / B328
3-я строка: CX9R
/ A2D8 / B328 / CX9R
4-я строка: DTBD
/ A2D8 / B328 / CX9R / DTBD
5-я строка: E373
/ A2D8 / B328 / CX9R / DTBD / E373
2010/11 / 02m / A2D8 / B328 / CX9R / DTBD / E373
��m�� 2010 /11/02 / A2D8 / B328 / CX9R / DTBD / E373

Мой главный вопрос: почему символы включаются в результирующие строки?что я делаю не так с указателями?

Ответы [ 4 ]

7 голосов
/ 29 октября 2010

strlen возвращает длину строки, не включая терминатор NULL; поэтому memcpy не копирует это, поэтому результирующая строка не заканчивается. То же самое относится и к вашим malloc с.

Вам нужно либо использовать strlen() + 1, либо использовать strcpy().

1 голос
/ 29 октября 2010

Если ваша цель - преобразовать «20101102A2D8B328CX9RDTBDE373» в «2010/11/02 / A2D8 / B328 / CX9R / DTBD / E373», тогда один из способов будет следующим:

// source string YYYYMMDD<20-char token>
char *src = "20101102A2D8B328CX9RDTBDE373";

// destination string, alloc space for source + 7 slashes + 1 null terminator
char *dest = (char *)calloc(1, strlen(src) + 7 + 1);

// now copy elements of src to dest, inserting intermediate slashes
<your code here>
1 голос
/ 29 октября 2010

Строки в C заканчиваются нулевым символом ('\0').Различные используемые вами строки (например, yrstr) недостаточно велики, чтобы содержать этот нулевой символ, и вы не помещаете в них нулевой символ.

Например, когда вы делаете это

strncpy(yrstr,mainstring,4);

в строку не добавляется нулевой символ, поскольку strncpy пропускает нулевой символ, если в целевой строке недостаточно места.Вам нужно добавить нулевой символ самостоятельно, например, так:

yrstr[4]='\0';

Для этого требуется, чтобы yrstr был достаточно большим, чтобы содержать как минимум пять символов.

0 голосов
/ 01 ноября 2010

Благодаря вашему вкладу результаты теперь были последовательными.Я хотел бы поблагодарить всех, кто участвовал и помог мне.Я публикую код, который включает в себя все ваши входные данные для следующего ученика, чтобы получить из него.здесь идет:

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

#define token "20101102A2D8B328CX9RDTBDE373"
#define SLASH "/"

int main()
{
    char *mainstring = (char*)malloc(strlen(token));
    char *nextstring = (char*)malloc(strlen(token));
    char tokenarr[50] = token;
    char patharr[50];
    char pathmem[50];
    char *fullstring = (char*)malloc(strlen(token));
    patharr[50]='\0';



    char yrstr[5];
    char monstr[3];    
    char daystr[3];

    yrstr[4] ='\0';
    monstr[2]='\0';
    daystr[2]='\0';



    memcpy(mainstring,token,strlen(token)+1);    
    strncpy(yrstr,mainstring,4);



    mainstring = mainstring +4;

    strncpy(monstr,mainstring,2); 


    mainstring = mainstring+2;    
    strncpy(daystr,mainstring,2);

    puts(yrstr);    
    puts(monstr); 
    puts(daystr);

    mainstring = mainstring +2;
    int i;

    for(i=0;i<5;i++)
    {
        memcpy(nextstring,mainstring,4);
        mainstring = mainstring +4;
        printf("The %d th string is:",i+1);        
        puts(nextstring);strcat(fullstring,SLASH);
        strcat(fullstring, nextstring);

        puts(fullstring);
    }

return 0;

}

Результат:

2010
11
02
The 1 th string is:A2D8
2010/11/02/A2D8
The 2 th string is:B328
2010/11/02/A2D8/B328
The 3 th string is:CX9R
2010/11/02/A2D8/B328/CX9R
The 4 th string is:DTBD
2010/11/02/A2D8/B328/CX9R/DTBD
The 5 th string is:E373
2010/11/02/A2D8/B328/CX9R/DTBD/E373
...