Reputation: 51
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
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
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