您需要解决几个问题才能将您的函数从简单地将分隔字符串打印到 stdout 到将分隔字符串保存在 ArrayOfString 中。在进行更改之前,让我们避免在代码中使用幻数。
char ArrayOfString[10][5];
在上面的ArrayOfString 中,10 和5 是幻数。它们是硬编码值,将管理从声明大小到所需验证检查以保护数组边界的所有内容。如果您需要一个常量,而不是硬编码值,请定义一个(或多个),例如
#include <stdio.h>
#include <string.h>
#define ROW 10
#define COL 5
char ArrayOfString[ROW][COL];
现在将你的字符串分成tokens。 C 库提供了一个专门用于将分隔字符串分隔为标记的函数。方便地命名为strtok。关于strtok,唯一需要注意的是它会修改字符串,所以如果您需要保留原件,请先复制一份。
要使用strtok (string, delims) 将string 分隔为delims 的标记,您对strtok 的第一次调用将string 作为第一个参数。所有后续调用都使用NULL 代替它。您可以对strtok 进行初始调用,然后使用while 循环来完成该过程,或者for 循环专门用于处理初始调用以及NULL 的所有后续调用。
例如,您的函数利用strtok 将string 分隔为令牌并提供size_t 返回复制到ArrayOfString 的令牌数可能类似于:
char ArrayOfString[ROW][COL];
size_t vSeparateSringByComma (char* string)
{
const char *delims = ",\n";
char *s = string;
size_t n = 0, len;
for (s = strtok (s, delims); s && n < ROW; s = strtok (NULL, delims))
if ((len = strlen (s)) < COL)
strcpy (ArrayOfString[n++], s);
else
fprintf (stderr, "error: '%s' exceeds COL - 1 chars.\n", s);
return n;
}
(注意:在复制到ArrayOfString[n++] 之前,您的数组边界如何通过n < ROW 检查和(len = strlen (s)) < COL 保护每个行数组边界) p>
(另请注意:如何不使用幻数,如果您以后更改ROW 或COL 的大小,只需要更改常量和通过使用常量,更改会自动合并到您的代码中)
您的示例程序将是:
int main(void) {
char string[] = "$,0,3,307,183,18,5,119,1,#";
size_t n = vSeparateSringByComma (string);
for (size_t i = 0; i < n; i++)
printf ("ArrayOfString[%zu] : '%s'\n", i, ArrayOfString[i]);
}
使用/输出示例
$ ./bin/arrayofstrings
ArrayOfString[0] : '$'
ArrayOfString[1] : '0'
ArrayOfString[2] : '3'
ArrayOfString[3] : '307'
ArrayOfString[4] : '183'
ArrayOfString[5] : '18'
ArrayOfString[6] : '5'
ArrayOfString[7] : '119'
ArrayOfString[8] : '1'
ArrayOfString[9] : '#'
使用strcspn 和strspn 而不是strtok
正如在 cmets 中所讨论的,使用strcspn 报告不包含分隔符的连续字符数,允许您确定每个字段的长度。然后您需要跳过分隔符(在许多情况下,分隔符可以由多个分隔符组成(例如$, 0, 3, ...)。
虽然strtok 将多个连续分隔符视为一个分隔符,但您需要一种类似的方式来跳过中间分隔符以定位您自己以读取下一个字段。 strspn 可以很好地使用相同的 delims,但这次报告的字符数仅由 delims 中的字符组成(允许您将其添加到您的 len,然后将 len 添加到 s为下一次阅读定位)
使用strcspn 和strspn 的简短变化可能是:
size_t vSeperateSringByComma (char* string)
{
const char *delims = ",\n";
char *s = string;
size_t n = 0, len;
while ((len = strcspn (s, delims))) { /* number of non-delim chars */
if (len < COL) { /* validate it will fit */
memcpy (ArrayOfString[n], s, len); /* copy len chars */
ArrayOfString[n++][len] = 0; /* nul terminate at len */
}
else
fprintf (stderr, "error: '%s' exceeds COL - 1 chars.\n", s);
len += strspn (s + len, delims); /* scan past delimiter(s) */
s += len; /* update s to beginning of next field */
}
return n;
}
(输出相同)
检查一下,如果您还有其他问题,请告诉我。