我是C语言的新手,所有这些字符串的东西都非常令人困惑。
程序这部分的目标是将一个字符串拆分为多个字符串,这样我就可以单独处理单词。
int SplitString(char * str, char * pieces[]) {
int i=1;
if ((pieces[0]=strtok(str," nt"))==NULL){
return 0;
}
while ((pieces[i]=strtok(str," nt"))!=NULL) {
i++;
}
return i;
}
/*****************************************************************************/
void CommandPros(char *str) {
char *pieces[100];
int numW = 0;
for (int i = 0; i < 100; i++) {
pieces[i] = (char *) malloc (100*sizeof(char));
}
numW = SplitString(str, pieces);
}
/*****************************************************************************/
void ReadEnter(char * str) {
fgets(str, 100, stdin);
}
/*****************************************************************************/
int main(){
int fin = 0;
char * strCommand;
strCommand = (char *) malloc (100*sizeof(char));
while (!fin) {
ReadEnter(strCommand);
CommandPros(strCommand);
}
return 0;
}
但是当我执行程序时,出现以下消息:
Segmentation fault: 11
您应该使用 NULL 作为从第二次调用开始的第一个参数strtok
替换while ((pieces[i]=strtok(str," nt"))!=NULL)
与while ((pieces[i]=strtok(NULL," nt"))!=NULL)
你的SplitString
函数过于复杂和错误。
你想要这个:
int SplitString(char * str, char * pieces[]) {
int i = 0;
char *token = strtok(str, " nt");
while (token != NULL) // while there are tokens
{
strcpy(pieces[i++], token); // copy the string, not the pointer
token = strtok(NULL, " nt"); // use NULL here, read the
// documentation of strtok
}
return i;
}
与您的问题没有直接关系:
CommandPros
函数非常笨拙:您为 100 个字符串分配内存,每个字符串都有 99 个字符的空间(+NUL 终止符(,这在大多数情况下太多了。
应仅分配所需的内存。代码的整体设计看起来是错误的。
你必须将 SplitString 中的第二个 strtok(( 修改为下面 while ((pieces[i]=strtok(NULL," \t"((!=NULL(
对 strtok 的第一次调用必须传递要进行标记化的 C 字符串,后续调用必须将 NULL 指定为第一个参数,这告诉函数继续标记您首先传入的字符串。
最好检查调用 C 库函数时返回的值,以确保操作成功。 在这种情况下,malloc()
和fgets()
关于:
/*****************************************************************************/
void ReadEnter(char * str) {
fgets(str, 100, stdin);
}
int main(){
int fin = 0;
char * strCommand;
strCommand = (char *) malloc (100*sizeof(char));
while (!fin) {
ReadEnter(strCommand);
CommandPros(strCommand);
}
需要有一些"一致"的方法来终止main()
中的循环。 注意调用fgets()
返回的值将很好地做到这一点。 建议:
int main( void )
{
char strCommand[ 100 ];
while ( fgets( strCommand, 100, stdin ) )
{
CommandPros(strCommand);
}
}
此外,函数:SplitString()
每次调用时都会从堆中再分配 100 个动态内存部分。 但是没有一个代码将其中的每一个(输入中的 100 * 行数(传递给free()
. 这会导致大量内存泄漏
函数:SplitString()
仅设置指向通过strtok()
找到的strCommand
中的每个区域的指针,并且期望100个分配的内存区域中的每一个都包含strtok()
Suggest找到的字符串的实际内容:
int SplitString( char * str, char * pieces[], int maxPieces )
{
int i = 0;
char *token = strtok(str, " nt");
while ( i < maxPieces && token != NULL )
{
strcpy(pieces[i++], token);
token = strtok(NULL, " nt");
}
return i;
}
在函数中:CommandPros()
局部变量:num
设置为在当前str
中找到的单词数,但从不用于任何内容。 编译器将输出有关此问题的警告消息。
此外,发布的代码包含一个"魔术"数字 100。 "魔术"数字是没有基础的数字,它们使代码更难理解、调试等。 建议使用enum
语句或#define
语句为该"魔术"数字提供一个有意义的名称,然后在整个代码中使用该有意义的名称。