[英]C split a string into individual words and save the individual words in an array
因此,假设用户键入“编程一二三”。 我将其保存在userTyped数组中,并将其传递给parse()函数。 我需要parse()函数来做到这一点
userargv [0]是程序
userargv [1]是一个
userargv [2]是两个
等等
我可以告诉它一定是涉及指针的东西,但我无法弄清楚。 代码如下:
int main(int argc, char **argv)
{
char userTyped[1000];
char* userargv[100];//this is where i need the parse() function to store the arguments to pass to execv
printf("typesomething>");
fgets(userTyped, 1000, stdin);
parse(userTyped, &userargv);
return 0;
}
int parse(char* userTyped, char* userargv){
const char whitespace[2] = " "; //the deliminator
char *strings;
strings = strtok(userTyped, whitespace);
while( strings != NULL )
{
strings = strtok(NULL, whitespace);
}
//THIS ALL WORKS, BUT I NEED TO DO SOMETHING LIKE userargv[i] = strings;
//OR *userargv[i] = &strings;
//OR SOMETHING LIKE THAT.
return 0;
}
您必须分配一个字符串数组(char **),并分配其每个元素,然后在其中复制所有找到的字符串;
// nb: the function prototype has been slightly modified
char** parse(char* userTyped, int *nargs){
const char whitespace[2] = " "; //the deliminator
char *strings;
char **arr;
int n = 0; // initially no element allocated
strings = strtok(userTyped, whitespace);
while( strings != NULL )
{
if( n ){ // if there are already allocated elements?
arr = realloc( arr, ( n + 1 ) * sizeof( char** ) );
}else{
arr = malloc( ( n + 1 ) * sizeof( char* ) );
}
if( !arr ){
perror( "parse" );
exit( -1 );
}
// duplicate strings
arr[ n ] = malloc( strlen( strings )+1 );
if( !arr[ n ] ){
perror( "parse" );
exit( -2 );
}
strcpy(arr[ n ] , strings); // make a copy of the string
n++;
strings = strtok(NULL, whitespace);
}
// call freeStrArr when done with arr;
//
*nargs = n; // save array size;
return arr; // return string array
}
// this how to free the returned array;
void freeStrArr(char ** strarr,int n){
while( n ){
n--;
free( strarr[ n ] );
}
free( strarr);
}
当想到需要从parse函数返回的内容时,您将知道要指向包含分配的内存块的指针数组,该数组包含usertyped
中的各个单词,但是您还需要知道有多少个单独的单词。 由于您将指针数组作为参数传递给函数本身进行操作,因此仅需要返回给定字符串中单个单词的数量。 您可以使用以下形式:
int parse (char **words, char *str);
( 注意:通过传递一个指针数组 ( 100
),您只能限制100个单词,如果超过该数字则没有机会重新分配。您可以传递一个指向char-charger *和如果需要,请重新分配。还请注意,如果您没有将负数作为错误条件返回,则为返回选择size_t
可能更合适)
使用strtok
,可以通过调整strtok
使用的分隔符来调整strtok
在何处以及如何分隔单词。 (例如,在句子"This. Not that."
如果只是在spaces
打断,则分隔的单词也将包含'.'
字符)。 为防止这种情况,您可以添加'.'
strtok
使用的分隔符字符串中的字符。 从这个角度来看,将分隔符列表作为参数传递给parse
函数也很有意义:
int parse (char **words, char *str, char *delims);
您可以使用初始调用以指定的原始字符串作为参数的strtok
,然后在另一个循环中通过传递NULL
作为参数来解析其余字符串。 或者,您可以在一个for
循环中处理这两种情况。 这只是形式问题,也可以。 一个例子:
int parse (char **words, char *str, char *delims)
{
int n = 0;
char *p;
for (p = strtok (str, delims); p; p = strtok (NULL, delims))
{
words[n++] = strdup (p); /* allocate/copy */
if (n == MAXW) { /* limit reached - realloc/break */
fprintf (stderr, "warning: MAXW reached.\n");
break;
}
}
return n;
}
一个简单的示例程序,它指定分隔符并将它们与数组和字符串一起传递给parse
函数,可以是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { MAXW = 100, MAXC = 1000 };
int parse (char **words, char *str, char *delims);
int main (void) {
char usertyped[MAXC] = {0};
char *userargv[MAXW] = {NULL};
char *delims = " \t\n.,:;";
int i, nwords = 0;
printf ("typesomething> ");
if (!fgets (usertyped, 1000, stdin)) {
fprintf (stderr, "error: invalid input.\n");
return 1;
}
if (!(nwords = parse (userargv, usertyped, delims))) {
fprintf (stderr, "error: parsed no words.\n");
return 1;
}
for (i = 0; i < nwords; i++)
printf ("userargv[%2d] : %s\n", i, userargv[i]);
for (i = 0; i < nwords; i++)
free (userargv[i]);
return 0;
}
int parse (char **words, char *str, char *delims)
{
int n = 0;
char *p;
for (p = strtok (str, delims); p; p = strtok (NULL, delims))
{
words[n++] = strdup (p); /* allocate/copy */
if (n == MAXW) { /* limit reached - realloc/break */
fprintf (stderr, "warning: MAXW reached.\n");
break;
}
}
return n;
}
使用/输出示例
$ ./bin/strtok_parse
typesomething> a quick brown fox jumps over the laszy dog.
userargv[ 0] : a
userargv[ 1] : quick
userargv[ 2] : brown
userargv[ 3] : fox
userargv[ 4] : jumps
userargv[ 5] : over
userargv[ 6] : the
userargv[ 7] : laszy
userargv[ 8] : dog
几个额外的笔记。 通常在C语言中,应避免使用camelCase变量。 因此是usertyped
而不是上面的userTyped
。 (另一个仅限表单的问题)。 由于strdup
为您分配了内存,因此应检查以确保返回的值不为NULL
(与malloc
或calloc
),以防止内存耗尽。 还要注意,您可以#define SOMECONST value
或者如上使用enum
定义常量。 如果您还有其他问题,请告诉我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.