在 C 中使用字符串数组时出现分段错误



我是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语句为该"魔术"数字提供一个有意义的名称,然后在整个代码中使用该有意义的名称。

相关内容

  • 没有找到相关文章

最新更新