如何将具有终止字符的字符串复制到C中的另一个字符串中?

时间:2017-05-29 19:21:36

标签: c string memory

我有这样的字符串

    char year_cp[5], mon_cp[3], date_cp[3];

    char *src;
    src = "2017-05-30";

我想在不同的缓冲区中存储年,月,日。我也尝试了strncpy()和sprintf()。喜欢这个

    strncpy(mon_cp,&src[4],2); //strncpy(mon_cp, src+4, 3);
    mon_cp[2] = '\0';
    printf("mon-cp %s\n",mon_cp);
    strncpy(year_cp,&src[0],4); //strncpy(year_cp, src+0, 5);
    year_cp[4] = '\0';
    printf("year-cp %s\n",year_cp);

即使我将src字符串作为

传递
    src = "20170530";

它只复制mon_cp,而不是将年份复制到year_cp

我遇到了分段错误。

请告诉我实现此目的的最佳方法

4 个答案:

答案 0 :(得分:3)

您应该使用sscanf(),如下所示:

char * src = "2017-05-30";
unsigned year, month, day;
if(sscanf(src, "%u-%u-%u", &year, &month, &day) < 3) {
    /* ERROR */
}

如果由于某种原因您需要将组件作为字符串,只需使用%s对您不起作用:您需要使用snprintf()来电转换回来。

答案 1 :(得分:1)

使用strtok和计数器。

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

int main(){

char s[11];
scanf("%s",s);
char token[2]="-";
int count=0;
char year[5],month[3],day[3];
char *split;
split=strtok(s,token);
while(split!=NULL){
    if(count==0){
    strcpy(year,split);
    }
    else if(count==1){
    strcpy(month,split);
    }
    else{
    strcpy(day,split);
    }
    split=strtok(NULL,token);
    count++;
}

printf("\n%s",month);
return 0;

}

请注意,这里我假设您的输入是一个常量格式。 &#34; 2017年5月30日&#34 ;. YYYY-MM-DD

另请注意,OP在strncpy中有一个轻微的错误...他正在使用错误的数组。它不是str_cp而是year_cp。

答案 2 :(得分:1)

您可以超出界限访问阵列。

char year_cp[5], mon_cp[3], date_cp[3];

...

mon_cp[3] = '\0';

如果mon_cp是包含三个元素的数组,则无法将第四个元素设置为零。

由于mon_cp[0]是第一个元素,mon_cp[1]是第二个元素。因此mon_cp[2]是第三个元素,mon_cp[3]是第四个元素。

如果需要带有第四个元素的数组,则需要创建一个包含四个元素的数组!

答案 3 :(得分:1)

使用regcomp和regexec的更多示例将解析 20170530 2017-05-30 。当i分别等于1,2,3时,从tmpvalue到year_cp,mon_cp或date_cp strcpy。

/*
 * parsedate.c
 * vi: set ts=4 sw=4 ic:  
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <regex.h>

int main (argc, argv)
int argc;
char    *argv[];
{
    /* nummatch is 4, Entire string and YYYY MM DD */
    int         nummatch=4;
    char        year_cp[5], mon_cp[3], date_cp[3];
    regex_t     dateregx;
    regmatch_t  pmatch[nummatch];
    int         i, rv;
    const char* pattern = "^([[:digit:]]{4})[^[:digit:]]?([[:digit:]]{2})[^[:digit:]]?([[:digit:]]{2})";
    char    dateline[80] = "2017-05/29";
    char        tmpvalue[256];

    /* Compile regular expression */
    if( regcomp( &dateregx, pattern, REG_EXTENDED ) != 0 ) {
        fprintf(stderr,"Pattern failed to compile.\n");
        return -1;
    }

    /* Execute regular expression */
    if( regexec( &dateregx, dateline, nummatch, pmatch, 0 ) != 0 ) {
        fprintf(stderr, "dateline <%s> does not match pattern <%s>\n",
        dateline, pattern );
        return -1;
    }

    /* Print values */
    for( i = 0; i < nummatch && pmatch[i].rm_so != -1; i++ ) {
        memset(tmpvalue, 0, 256 );
        strncpy( tmpvalue, &dateline[pmatch[i].rm_so], pmatch[i].rm_eo-pmatch[i].rm_so);
        printf("matched pmatch[%d].rm_so: %d    pmatch[%d].rm_eo: %d  -   \"%s\"\n", i, (int)pmatch[i].rm_so, i, (int)pmatch[i].rm_eo, tmpvalue);
        if ( i == 1 ) {
            strcpy( year_cp, tmpvalue );
        } else if ( i == 2 ) {
            strcpy( mon_cp, tmpvalue );
        } else if ( i == 3 ) {
            strcpy( date_cp, tmpvalue );
        }
    }

    printf( "Year: %s\tMonth: %s\tDay: %s\n", year_cp, mon_cp, date_cp );
    return 0;

}