strtok 没有正确分割字符串
strtok doesn't split the string properly
当我将“/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin”传递到我的函数中时,当我打印每个标记时,我只得到 3 个输出(而不是5).检查 100 次后我没有发现任何问题。但每次它只打印 3 个输出。
/usr/bin
/bin
/u/usr/bin
(空)
char** tokenised(char* directories) {
char** directoryArray = malloc(1000*sizeof(char*));
char *token;
int i = 0;
//First token
token = strtok(directories, ":");
while(token != NULL)
{
directoryArray[i] = strdup(token);
token = strtok(NULL, ":");
i++;
}
int j = 0;
while(directoryArray[j] != NULL) {
printf("%s\n", directoryArray[j]);
j++;
}
return directoryArray;
}
调用tokenised的函数,有问题
int searchForFile(int argc, char *argv[]) {
char* fileName = argv[0];
char* pathBuffer = malloc(sizeof(PATH)+1);
strcpy(pathBuffer, PATH);
int i = 0;
printf("%s\n", PATH);
char** directoryArray = tokenised(pathBuffer);
printf("%s\n", directoryArray[4]);
while(directoryArray[i] != NULL) {
printf("%i\n", i);
printf("Searching directory: '%s'\n", directoryArray[i]);
//Form an address out 2 strings
char *address = malloc(sizeof(char)*strlen(directoryArray[i])+sizeof(char)*strlen(fileName)+1*sizeof(char));
strcpy(address, directoryArray[i]);
strcat(address, "/");
strcat(address, fileName);
argv[0] = address;
if(execute(argc, argv) == 0) {
return 0;
}
i++;
}
printf("Search for file: '%s' failed.", fileName);
return 1;
}
在这个循环之后
while(token != NULL)
{
directoryArray[i] = strdup(token);
token = strtok(NULL, ":");
i++;
}
写入
directoryArray[i] = NULL;
或
directoryArray[i] = token;
在这种情况下,下面的循环是正确的
int j = 0;
while(directoryArray[j] != NULL) {
printf("%s\n", directoryArray[j]);
j++;
}
编辑: 附加代码示例后,此语句
char *address = malloc(sizeof(char)*strlen(directoryArray[i])+sizeof(char)*strlen(fileName)+1*sizeof(char));
必须改为
char *address = malloc( strlen(directoryArray[i])+strlen(fileName)+2);
^^^
因为您还向字符串附加了一个斜杠
strcat(address, "/");
问题出在你的制作方式上pathBuffer
。根据您的评论, PATH
是一个指针。因此,调用
char* pathBuffer = malloc(sizeof(PATH)+1);
strcpy(pathBuffer, PATH);
为指针加一个字节分配内存,而不是为PATH
指针的内容分配内存。将长输入字符串复制到这个短缓冲区会导致未定义的行为。最有可能的是,字符串尾部的内存与其他一些数据结构共享,导致字符串在 strtok
开始处理之前被截断。您可以通过在 tokenised()
函数开头打印 directories
字符串来确认这一点。
由于您在其他地方使用strdup
,将上面的行更改为
char* pathBuffer = strdup(PATH);
将解决问题。
当我将“/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin”传递到我的函数中时,当我打印每个标记时,我只得到 3 个输出(而不是5).检查 100 次后我没有发现任何问题。但每次它只打印 3 个输出。
/usr/bin
/bin
/u/usr/bin
(空)
char** tokenised(char* directories) {
char** directoryArray = malloc(1000*sizeof(char*));
char *token;
int i = 0;
//First token
token = strtok(directories, ":");
while(token != NULL)
{
directoryArray[i] = strdup(token);
token = strtok(NULL, ":");
i++;
}
int j = 0;
while(directoryArray[j] != NULL) {
printf("%s\n", directoryArray[j]);
j++;
}
return directoryArray;
}
调用tokenised的函数,有问题
int searchForFile(int argc, char *argv[]) {
char* fileName = argv[0];
char* pathBuffer = malloc(sizeof(PATH)+1);
strcpy(pathBuffer, PATH);
int i = 0;
printf("%s\n", PATH);
char** directoryArray = tokenised(pathBuffer);
printf("%s\n", directoryArray[4]);
while(directoryArray[i] != NULL) {
printf("%i\n", i);
printf("Searching directory: '%s'\n", directoryArray[i]);
//Form an address out 2 strings
char *address = malloc(sizeof(char)*strlen(directoryArray[i])+sizeof(char)*strlen(fileName)+1*sizeof(char));
strcpy(address, directoryArray[i]);
strcat(address, "/");
strcat(address, fileName);
argv[0] = address;
if(execute(argc, argv) == 0) {
return 0;
}
i++;
}
printf("Search for file: '%s' failed.", fileName);
return 1;
}
在这个循环之后
while(token != NULL)
{
directoryArray[i] = strdup(token);
token = strtok(NULL, ":");
i++;
}
写入
directoryArray[i] = NULL;
或
directoryArray[i] = token;
在这种情况下,下面的循环是正确的
int j = 0;
while(directoryArray[j] != NULL) {
printf("%s\n", directoryArray[j]);
j++;
}
编辑: 附加代码示例后,此语句
char *address = malloc(sizeof(char)*strlen(directoryArray[i])+sizeof(char)*strlen(fileName)+1*sizeof(char));
必须改为
char *address = malloc( strlen(directoryArray[i])+strlen(fileName)+2);
^^^
因为您还向字符串附加了一个斜杠
strcat(address, "/");
问题出在你的制作方式上pathBuffer
。根据您的评论, PATH
是一个指针。因此,调用
char* pathBuffer = malloc(sizeof(PATH)+1);
strcpy(pathBuffer, PATH);
为指针加一个字节分配内存,而不是为PATH
指针的内容分配内存。将长输入字符串复制到这个短缓冲区会导致未定义的行为。最有可能的是,字符串尾部的内存与其他一些数据结构共享,导致字符串在 strtok
开始处理之前被截断。您可以通过在 tokenised()
函数开头打印 directories
字符串来确认这一点。
由于您在其他地方使用strdup
,将上面的行更改为
char* pathBuffer = strdup(PATH);
将解决问题。