我正在尝试为strtok()
创建包装器函数,但是在标记输入字符串之前,我希望该函数按如下方式处理字符串
1.如果第一个字符是,
,则插入一个字符说N
作为第一个字符,后跟,
2.如果两个,
字符紧跟在后,则在它们之间插入一个说N
的字符。
3.如果,
和;
字符紧随其后,则在它们之间插入一个说N
的字符。
尝试在strncpy()
之前重新分配。
str = realloc(str, (strlen(array) + 1) * sizeof(char));
我的解决方案:
#define ARRAY_SIZE 100000
int
utils_to_array(char **ret, char *str, char *delim)
{
char array[ARRAY_SIZE];
for (int y = 0, z = 0; str[y] != '\0'; y++, z++){ /* LINE 43*/
if ((str[y] == '\0') && (str[y + 1] == delim[0])){ /* ,*/
array[z] = 'N';
++y;
++z;
array[z] = ',';
} else if ((str[y] == delim[0]) && (str[y + 1] == delim[0])) { /*,, */
array[z] = str[y];
z++;
array[z] = 'N';
y++;
z++;
array[z] = str[y];
} else if ((str[y] == delim[0]) && (str[y + 1] == delim[1])) { /* ,; */
array[z] = str[y];
z++;
array[z] = 'N';
y++;
z++;
array[z] = str[y];
} else {
array[z] = str[y];
}
}
str = strncpy(str, array, strlen(array)); /* LINE 71 */
size_t n = 0;
for (char *p = strtok(str, delim); p ; p = strtok(NULL, delim)) { /* LINE 74 */
ret[n++] = p;
}
return 0;
}
Valgrind mem测试:
==7534== Conditional jump or move depends on uninitialised value(s)
==7534== at 0x4C2CAA8: __strlen_sse42 (vg_replace_strmem.c:462)
==7534== by 0x400BBA: utils_to_array (fxt_utils.c:71)
==7534== by 0x400F4A: parser_gsection_new (fxt_parser.c:115)
==7534== by 0x40096E: main (test_parser.c:10)
==7534==
==7534== Use of uninitialised value of size 8
==7534== at 0x54DAB1E: strtok (in /usr/lib64/libc-2.17.so)
==7534== by 0x400C3D: utils_to_array (fxt_utils.c:74)
==7534== by 0x400F4A: parser_gsection_new (fxt_parser.c:115)
==7534== by 0x40096E: main (test_parser.c:10)
==7534==
==7534== Use of uninitialised value of size 8
==7534== at 0x54DAB4E: strtok (in /usr/lib64/libc-2.17.so)
==7534== by 0x400C3D: utils_to_array (fxt_utils.c:74)
==7534== by 0x400F4A: parser_gsection_new (fxt_parser.c:115)
==7534== by 0x40096E: main (test_parser.c:10)
==7534==
==7534== Conditional jump or move depends on uninitialised value(s)
==7534== at 0x54DAB51: strtok (in /usr/lib64/libc-2.17.so)
==7534== by 0x400C3D: utils_to_array (fxt_utils.c:74)
==7534== by 0x400F4A: parser_gsection_new (fxt_parser.c:115)
==7534== by 0x40096E: main (test_parser.c:10)
==7534==
==7534==
==7534== HEAP SUMMARY:
==7534== in use at exit: 18,812 bytes in 7 blocks
==7534== total heap usage: 7 allocs, 0 frees, 18,812 bytes allocated
==7534==
==7534== LEAK SUMMARY:
==7534== definitely lost: 208 bytes in 1 blocks
==7534== indirectly lost: 0 bytes in 0 blocks
==7534== possibly lost: 0 bytes in 0 blocks
==7534== still reachable: 18,604 bytes in 6 blocks
==7534== suppressed: 0 bytes in 0 blocks
==7534== Rerun with --leak-check=full to see details of leaked memory
==7534==
==7534== For counts of detected and suppressed errors, rerun with: -v
==7534== Use --track-origins=yes to see where uninitialised values come from
==7534== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
如果我使用
if (str[0] == ',') { /* LINE 44 */
我收到以下valgrind错误
> ==11195== Conditional jump or move depends on uninitialised value(s)
> ==11195== at 0x400B79: utils_to_array (fxt_utils.c:43)
> ==11195== by 0x400F1D: parser_gsection_new (fxt_parser.c:115)
> ==11195== by 0x40096E: main (test_parser.c:10)
> ==11195==
> ==11195== Conditional jump or move depends on uninitialised value(s)
> ==11195== at 0x4C2CAA8: __strlen_sse42 (vg_replace_strmem.c:462)
> ==11195== by 0x400B8D: utils_to_array (fxt_utils.c:72)
> ==11195== by 0x400F1D: parser_gsection_new (fxt_parser.c:115)
> ==11195== by 0x40096E: main (test_parser.c:10)
> ==11195==
> ==11195==
> ==11195== Process terminating with default action of signal 11 (SIGSEGV)
> ==11195== Bad permissions for mapped region at address 0x1FFEFFFD6A
> ==11195== at 0x1FFEFFFD6A: ???
> ==11195== by 0x1FFEFFFD7F: ???
> ==11195== by 0x2C4E2C4E2C4DFFFF: ???
> ==11195== by 0x2C4E2C4E2C4E2C4D: ???
> ==11195== by 0x2C4E2C4E2C4E2C4D: ???
> ==11195== by 0x2C4E2C4E2C4E2C4D: ???
> ==11195== by 0x2C4E2C4E2C4E2C4D: ???
> ==11195== by 0x2C4E2C4E2C4E2C4D: ???
> ==11195== by 0x2C4E2C4E2C4E2C4D: ???
> ==11195== by 0x2C4E2C4E2C4E2C4D: ???
> ==11195== by 0x2C4E2C4E2C4E2C4D: ???
> ==11195== by 0x2C4E2C4E2C4E2C4D: ???
> ==11195==
> ==11195== HEAP SUMMARY:
> ==11195== in use at exit: 18,812 bytes in 7 blocks
> ==11195== total heap usage: 7 allocs, 0 frees, 18,812 bytes allocated
> ==11195==
> ==11195== LEAK SUMMARY:
> ==11195== definitely lost: 208 bytes in 1 blocks
> ==11195== indirectly lost: 0 bytes in 0 blocks
> ==11195== possibly lost: 0 bytes in 0 blocks
> ==11195== still reachable: 18,604 bytes in 6 blocks
> ==11195== suppressed: 0 bytes in 0 blocks
> ==11195== Rerun with --leak-check=full to see details of leaked memory
> ==11195==
> ==11195== For counts of detected and suppressed errors, rerun with: -v
> ==11195== Use --track-origins=yes to see where uninitialised values come from
> ==11195== ERROR SUMMARY: 3 errors from 2 contexts (suppressed: 0 from 0)
字符串输入示例:
,, 126HC:\ Users \ 410239 \ Documents \ Work \ Queries \ Lapa Parts 17-08-2017 \ AA00001106762_Ao_REINFORCEMENT \ AA00001106762_AO_REINFORCEMENT.stp,30HAA00001106762_AO_REINFORCEMENT,22HAutodesk Inventor 2016,7Hunknown,32,38,7,99, 15,,1.,2,2HMM,1,0.08,15H20180314.163749,0.01,10000。,4Hnone,4Hnone,11,0, 15H20170818.085306;
答案 0 :(得分:0)
由于strsep()
可以处理空字段,因此在字段为空时不再需要插入N。这就是我使用@rici发送的linux手册页和链接解决问题的方式:
https://github.com/freebsd/freebsd/blob/master/sys/libkern/strsep.c
Is there a windows variant of strsep()
int
utils_to_array(char **ret, char *str, char *delim)
{
size_t count = 0;
char *tok;
while((tok = strsep(&str, delim)) && count < PARAM_MAX)
ret[count++] = tok;
return 0;
}