Jerry Smith
Jerry Smith

Reputation: 51

Passing substring in C

I've spent last night debugging this little piece of code. I have two data text files, both contain 18000 chars. Id like to split these 18000 into two sub-strings each of 100 chars, that makes 180 iterations.

The tricky thing is, in the first 180 iterations the size of both sub-strings is fine. After 18 iterations, the sizes of the sub-strings are 0.

Both files were opened properly. I can print them and so on. I tried to allocate the sub-strings in all the possible ways I could think of but could find no solution so far.

int main(int argc, char const *argv[]) { 

    //Ive loaded two files into two strings buff1 and buff2 both size of 18000 chars
    //It works fine with small data example, I dunno why but eventually I have work with much more bigger data set
    //Id like to divide them into 100 char long pieces and do some stuff with that 

    char *substrA;      //substring for buff1
    char *substrB;      //substring for buff2

    substrA = malloc((wlen+1)*sizeof(char));        //word length wlen=100
    substrA = malloc((wlen+1)*sizeof(char));

    for (int i= 0; i <numOfSubProblems; ++i){   //numOfSubProblems = 18000/100

        strncpy(substrA, buff1+i*wlen, wlen);
        strncpy(substrB, buff2+i*wlen, wlen);
        substrA[wlen] = '\0';
        substrA[wlen] = '\0';

        int lenA = strlen(substrA);
        int lenB = strlen(substrB);
        printf("STRA a STR B: %d %d \n",lenA,lenB);

        DoSomething(substrA,substrB,i);  //some parser and other functionality
    }
    return 0;
}

Upvotes: 1

Views: 209

Answers (2)

Michael F
Michael F

Reputation: 40830

Use snprintf.

You may not be dealing with formatting strings, but at least it is a sane API. Also make sure to round up when determining the number of subproblems:

#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

#define PROBSIZE 18002

int main (int argc, char **argv) {
    char input[PROBSIZE];

    for (size_t i = 0; i < PROBSIZE; ++i) {
        input[i] = 'A' + (i % 10);
    }

    const size_t wlen = 10;
    char *subA = malloc (wlen + 1);
    if (!subA) {
        return EXIT_FAILURE;
    }

    for (int i = 0; i < (PROBSIZE + wlen - 1) / wlen; ++i) {
        /* If there's no error, guarantees `wlen` characters copied */
        int err = snprintf(subA, wlen + 1, "%s", input + i * wlen);

        if (err < 0) {
            fprintf(stderr, "snprintf encountered an error\n");
            return EXIT_FAILURE;
        }

        /* In absence of errors, we expect that the return value is
         * always >= wlen + 1, except the last iteration.
         */
        assert(err >= wlen + 1 || i == ((PROBSIZE + wlen - 1) / wlen) - 1);

        printf("%s\n", subA);
    }

    return EXIT_SUCCESS;
}

Upvotes: 0

Karsten Koop
Karsten Koop

Reputation: 2524

strncpy does not null-terminate the destination string. So you have to do

strncpy(subA, buff1+i*wlen, wlen);
subA[wlen] = '\0';
strncpy(subB, buff2+i*wlen, wlen);
subB[wlen] = '\0';

Otherwise you cannot use strlen, and you access the buffers behind their end when doing so.

Upvotes: 7

Related Questions