我正在编写一个C
程序,该程序将解析字符串数组中逗号分隔的字符串。
我已经尝试了打印以逗号分隔的字符串的源代码。但是我希望这些字符串存储在字符串数组中。以下代码使用strcspn
并使用以下行
printf("%.*s\n", (int)field_len, s);
打印我听不懂的字符串。如何在字符串数组中传输打印的字符串?
#include <stdio.h>
#include <string.h>
char ArrayOfString[10][5];
void vSeparateSringByComma(char* string)
{
const char delims[] = ",";
const char *s = string;
int i = 0, j;
do
{
size_t field_len = strcspn(s, delims);
printf("%.*s\n", (int)field_len, s);
s += field_len;
i++;
}
while (*s++);
}
int main() {
char string[] = "$,0,3,307,183,18,5,119,1,#";
vSeparateSringByComma(string);
}
我得到的输出是
$
0
3
307
183
18
5
119
1
#
(每个字符串后都有一个换行符) 很好。我的问题是将这些字符串传输到我的字符串数组中。
有什么建议吗?
答案 0 :(得分:3)
将函数转换为从简单打印分隔的字符串到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
循环来处理初始调用以及所有后续的{{ 1}}。
例如,您使用NULL
将strtok
分离为令牌并提供string
返回的复制到size_t
的令牌数量的函数可能类似于:>
ArrayOfString
(注意:如何在复制到{{1}之前通过用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;
}
进行检查来保护数组边界以及如何用n < ROW
保护每个行数组边界})
(也请注意::如果不将来更改(len = strlen (s)) < COL
或ArrayOfString[n++]
的大小,那么不使用魔术数字的方式,常量需要更改,并且通过使用常量,该更改会自动并入整个代码中
您的示例程序将是:
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
)。
尽管strcspn
将多个顺序定界符视为一个定界符,但您将需要一种类似的方法来跳过中间的定界符,以定位自己的位置以读取下一个字段。 $, 0, 3, ...
在使用相同的strtok
时可以很好地工作,但是这次报告的字符数仅由strspn
中的字符组成(允许您将其添加到delims
和然后从delims
到len
进行下一次阅读)
使用len
和s
的简短变化可能是:
strcspn
(输出相同)
仔细检查一下,如果还有其他问题,请告诉我。
答案 1 :(得分:1)
替换
printf("%.*s\n", (int)field_len, s);
使用
sprintf(ArrayOfString[i],"%.*s\n", (int)field_len, s);
然后您可以使用打印第四个元素
for( i=0 ; i<4 ; i++)
printf("%s" , ArrayOfString[i] );
答案 2 :(得分:0)
我已经了解了标准功能strtok()
和strcspn()
,并且正在发布解决方案的两个版本。
使用strtok()
#include <stdio.h>
#include <string.h>
#define ROW 10
#define COL 30
char ArrayOfString[ROW][COL];
size_t vSeperateSringByComma_New(char* string, char *delims)
{
char *p;
p = strtok (string,delims);
int i = 0,j;
while (p!= NULL)
{
strcpy(ArrayOfString[++i], p);
p = strtok (NULL, delims);
}
return i;
}
int main ()
{
char string[] ="$,0,3,307,183,18,5,119,1,#";
char delim[] = ",:";
printf ("String \"%s\" is split into tokens:\n",string);
size_t len = vSeperateSringByComma_New (string, delim);
int i;
for (i = 0; i < len+1; i++) {
printf ("%s\n",ArrayOfString[i]);
}
return 0;
}
使用strcspn()
#include <stdio.h>
#include <string.h>
#define ROW 10
#define COL 30
char ArrayOfString[ROW][COL];
size_t vSeperateSringByComma(char* string, char *delims)
{
const char *s = string;
int i = 0;
do {
size_t field_len = strcspn(s, delims);
sprintf(ArrayOfString[++i],"%.*s", (int)field_len, s);
s += field_len;
} while (*s++);
return i;
}
int main() {
char string[] = "$,0,3,307,183,18,5,119,1,#";
char delims[] = ",";
printf ("String \"%s\" is split into tokens:\n",string);
int len = vSeperateSringByComma(string, delims);
int i;
for (i = 0; i < len+1; i++) {
printf ("%s\n",ArrayOfString[i]);
}
}
感谢您的建议
答案 3 :(得分:0)
使用strncpy()将值放入数组。此 char * strncpy(char * dest,const char * src,size_t n)从src指向目标的字符串中最多复制n个字符。
do
{
size_t field_len = strcspn(str, delims);
printf("%.*s\n", (int)field_len, str);
strncpy (ArrayOfString[cnt++], str, (int)field_len);
str += field_len;
i++;
} while (*str++);