使用C操作指针

使用C操作指针,c,memory,pointers,allocation,C,Memory,Pointers,Allocation,在使用C语言中的指针时,我遇到了一个非常不一致的结果,我正在使用一个令牌,它是一个字节字符串,我需要创建一个目录路径。 令牌由日期作为前缀组成,格式为20101129(2010-10-29),随后是一个20字节的字符串,因此令牌看起来像20101102A2D8B328CX9RDTBDE373,该方法应该返回类似于2010/11/02/A2D8/B328/CX9R/DTBD/E373的路径 现在使用我在下面提供的代码中使用的方法,返回包含不需要的字符的字符串,而代码看起来正常,下面提供了代码 #i

在使用C语言中的指针时,我遇到了一个非常不一致的结果,我正在使用一个令牌,它是一个字节字符串,我需要创建一个目录路径。 令牌由日期作为前缀组成,格式为20101129(2010-10-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;

}
#包括
#包括
#包括
#包括
#定义令牌“20101102A2D8B328CX9RDTBDE373”
#定义斜杠“/”
int main()
{
char*mainstring=(char*)malloc(strlen(token));
char*nextstring=(char*)malloc(strlen(token));
char tokenarr[50]=令牌;
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(主环、令牌、strlen(令牌));
memcpy(yrarr,tokenarr,4);
strncpy(yrstr,mainstring,4);
memcpy(yrmem,梅斯特林,4);
puts(yrarr);
看跌期权(YRST);
puts(yrmem);
主环=主环+4;
memcpy(monarr,tokenarr+4,2);
strncpy(monstr,mainstring,2);
memcpy(monmem,mainstring,2);
puts(monarr);
看跌期权;
puts(monmem);
主环=主环+2;
memcpy(dayarr、tokenarr+6,2);
strncpy(daystr,mainstring,2);
memcpy(daymem,mainstring,2);
看跌期权(dayarr);
看跌期权(daystr);
看跌期权(daymem);
strcat(patharr,yrarr);strcat(pathmem,yrmem);
strcat(patharr,“/”);strcat(pathmem,斜杠);
strcat(patharr,monarr);strcat(pathmem,monmem);
strcat(patharr,“/”);strcat(pathmem,斜杠);
strcat(patharr,dayarr);strcat(pathmem,daymem);
put(patharr);
puts(路径记忆);
主环=主环+2;
int i;

for(i=0;i
strlen
返回字符串的长度,不包括空终止符;因此
memcpy
不会复制该长度,因此结果字符串不会终止。这同样适用于
malloc
s


您需要使用
strlen()+1
,或者使用
strcpy()

C中的字符串以空字符(
'\0'
)结尾。您使用的各种字符串(例如
yrstr
)都不够大,无法包含此空字符,并且您没有将空字符放入其中

例如,当您这样做时

strncpy(yrstr,mainstring,4);
没有向字符串添加空字符,因为如果目标字符串中没有足够的空间,请忽略空字符。您需要自己添加空字符,例如:

yrstr[4]='\0';

这需要
yrstr
足够大,至少可以包含五个字符。

如果您的目标是将“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>
//源字符串YYYYMMDD
char*src=“20101102A2D8B328CX9RDTBDE373”;
//目标字符串,源的alloc空格+7斜杠+1空终止符
char*dest=(char*)calloc(1,strlen(src)+7+1);
//现在将src的元素复制到dest,插入中间斜杠

多亏了您的输入,结果现在是一致的。我要感谢所有参与和帮助我的人。我发布了代码,其中包括您的所有输入,供下一位学员学习。下面是:

#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;

}

只有一个变量指向malloc()返回的地址,然后修改该变量,这是非常糟糕的样式为了安全起见,请在指针上保存原始值不变。在开始时复制主字符串指针,然后对其进行操作。细节点:20101129是2010年11月29日。感谢您的回复,将让您知道更新的更改。注意,像
yrstr[4]
这样的数组也需要
yrstr[5]
允许尾部空值。在不分配strlen()的情况下使用strcpy()+1调用未定义的行为-写入超出分配空间的末尾。虽然此代码可能看起来运行正常,但其中存在错误。例如,在第11行中,您为主字符串分配了strlen(令牌)字节,但稍后在第31行中,您复制了strlen(token)+1字节从token进入mainstring。快速跟进:我编译并运行了这段代码,错误确实有影响。运行代码的结果不正确,与您看到的不匹配。感谢您关注细节。
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