我昨晚花了很多时间调试这段代码。我有两个数据文本文件,都包含18000个字符。我想将这些18000分成两个子串,每个子串100个字符,这样就可以进行180次迭代。
棘手的是,在前180次迭代中,两个子串的大小都很好。经过18次迭代后,子串的大小为0.
两个文件都已正确打开。我可以打印它们等等。我尝试以我能想到的所有可能方式分配子字符串,但到目前为止找不到解决方案。
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;
}
答案 0 :(得分:7)
strncpy
不会终止目标字符串。所以你必须这样做
strncpy(subA, buff1+i*wlen, wlen);
subA[wlen] = '\0';
strncpy(subB, buff2+i*wlen, wlen);
subB[wlen] = '\0';
否则你不能使用strlen
,并且在这样做的时候访问它们后面的缓冲区。
答案 1 :(得分:0)
使用snprintf
。
您可能没有处理格式化字符串,但至少它是一个理智的API。还要确保在确定子问题的数量时向上舍入:
#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;
}