Search code examples
cconcatenationstrcat

Concatenating a string and numbers in C


I have a program that has to count the number of duplicate characters in a string. For example "aaabcc" should return "a3b1c2" and "aaabcccc..a" should return "a3b1c4.2a1". I am currently using sprintf to concatenate the string and numbers like this: sprintf(s, "%s%c%d", s, prev, count);, where s is the string containing the result. But that causes an error since I am using "s" as an input and also as the destination. Is there some way around this?

This is my code right now:

    char *s = (char *)malloc(sizeof(char) * 100);
    char prev = argv[1][0];
    if(isdigit(prev)!=0){
        printf("%s","ERROR");
        return 0;
    }
    
    int count = 1;
    for(int i=1; i<strlen(argv[1]); i++){
        if(isdigit(argv[1][i])!=0){
            printf("%s","ERROR");
            return 0;
        }
        
        //check if same as previous letter
        if(prev==argv[1][i]){
            count++;
        }else{
           //add letter and count to string
            //problem
            sprintf(s, "%s%c%d", s, prev, count);
            
            count = 1;
        }
        
        //update prev
        prev=argv[1][i];
    }
    
    //add it to string
    //problem
    sprintf(s, "%s%c%d", s, prev, count);
    
    //check if result is smaller than input
    if(strlen(s) > strlen(argv[1])){
        printf("%s\n", argv[1]);
    }else{
        printf("%s\n", s);
    }
    free(s);

Solution

  • Use a different buffer for sprintf(), then concatenate to s with strcat().

    Make sure you initialize s to an empty string after allocating it.

    Instead of allocating a hard-coded size for s, allocate a string big enough for the worst case (every character repeated just once, so it's a1b1c1...).

    temp can be a short, fixed-size string, since it just has to hold the length of one run.

    char *s = malloc(strlen(argv[1]) * 2 + 1);
    s[0] = '\0';
    char temp[20];
    char prev = argv[1][0];
    if(isdigit(prev)!=0){
        printf("%s","ERROR");
        return 0;
    }
        
    int count = 1;
    for(int i=1; i<strlen(argv[1]); i++){
        if(isdigit(argv[1][i])!=0){
            printf("%s","ERROR");
            return 0;
        }
            
        //check if same as previous letter
        if(prev==argv[1][i]){
            count++;
        }else{
            //add letter and count to string
            sprintf(temp, "%c%d", prev, count);
            strcat(s, temp);
                
            count = 1;
        }
            
        //update prev
        prev=argv[1][i];
    }
        
    //add it to string
    sprintf(temp, "%s%c%d", prev, count);
    strcat(s, temp);
        
    //check if result is smaller than input
    if(strlen(s) > strlen(argv[1])){
        printf("%s\n", argv[1]);
    }else{
        printf("%s\n", s);
    }
    free(s);