【问题标题】:How to copy the string which has termination characters into another string in C?如何将具有终止字符的字符串复制到C中的另一个字符串中?
【发布时间】:2017-05-29 19:21:36
【问题描述】:

我有这样的字符串

    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中

我遇到了分段错误。

请告诉我实现这一目标的最佳方法

【问题讨论】:

  • 您必须确保在 C 中的字符串末尾始终有一个 NUL 字符“\0”。C 中的所有 str* 函数都存在无法给出有用结果的情况。
  • strncpy(mon_cp,&src[4],2),第一个月字符的索引不是src[4],而是src[5],基于之前的定义src = "2017-05-30";。但是确实与后面的定义 src = "20170530"; 一致。所以投票结束,因为问题需要 MCVE。
  • 发布的代码看起来不错。问题出在代码的其他部分。请发送minimal reproducible example - 这将使问题可以回答或完全消除问题。
  • strtok 就是你要找的东西
  • 如果我使用 char 数组而不是 char 指针会有什么不同吗? @大卫施瓦茨

标签: c string memory


【解决方案1】:

你应该使用sscanf(),像这样:

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

如果由于某种原因您需要将组件作为字符串,则仅使用 %s 将不适合您:您需要使用 snprintf() 调用或类似的方式转换回来。

【讨论】:

  • 如果我的字符串没有“-”或“/”怎么办?
  • @emb-pro 如果您希望将字符串解析为多种格式,那么您需要让您的代码确定使用了哪种格式并进行相应的解析。学习使用 regex(3) 函数,如 regcompregexec,您将能够解析 YYYYMMDDYYYY/MM/DDYYYY- MM-DD 无需检查字符串是否包含分隔符。
【解决方案2】:

使用 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;

}

请注意,这里我假设您的输入是常量格式。 “2017-05-30”。 YYYY-MM-DD

还请注意,OP 在 strncpy 中出现了一年的小错误......他使用了错误的数组。不是str_cp,而是year_cp。

【讨论】:

  • 这段代码会在 10000 年发生故障(不是任何人都应该担心)
【解决方案3】:

你越界访问你的数组。

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] 是第四个元素。

如果你需要一个有第四个元素的数组,你需要创建一个有四个元素的数组!

【讨论】:

    【解决方案4】:

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

    /*
     * 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;
    
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-09
      • 2022-11-30
      • 2014-05-26
      • 2019-06-25
      • 2015-02-05
      • 1970-01-01
      • 2021-05-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多