虽然不是 100% 清楚你想要用你的代码完成什么,但你对多个指针的使用有点尴尬。
应该为您敲响警钟的第一件事是您需要明确地转换为(char)。如果你发现自己试图通过强制转换来绕过编译器警告或错误 -- STOP -- 你做错了。
如果您的目标是为execvp(或类似的)提供最多BUFFERSIZE 参数,那么您只需将myargv 声明为指向char 的指针数组,例如
char *myargv[BUFFERSIZE] = {NULL}; /* array of pointers - init NULL */
strtok 返回的每个指针都可以用作execvp 的参数数组,如果将数组初始化为所有NULL 指针并填充不超过BUFFERSIZE - 1,则确保始终提供execvp 的参数数组,并在最后一个参数之后提供所需的标记 NULL。
您可以以任何您喜欢的方式为strtok 声明分隔符,但由于您使用#define 正确定义了常量,因此没有理由不为您的strtok 分隔符添加常量,例如
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFERSIZE 256
#define PROMPT "myShell >> "
#define DELIM " \n"
如果您没有在代码中使用argc 或argv,那么main() 的正确声明是:
int main (void) {
(参见:C11 Standard §5.1.2.2.1 Program startup p1 (draft n1570)。另请参见:See What should main() return in C and C++?)
如果您只是阅读该行并标记该行以与execvp 一起使用,那么声明和初始化您的变量在循环范围内确保它们正确地重新- 初始化每次迭代,例如
while (1) {
size_t ndx = 0, /* line index */
n = 0; /* line alloc size (0, getline decides) */
ssize_t nchr = 0; /* return (chars read by getline) */
char *line = NULL, /* buffer to read each line */
*myargv[BUFFERSIZE] = {NULL}; /* array of pointers - init NULL */
通过将上面的inputSize、我的nchr 声明为ssize_t(POSIX getline 的正确返回类型),您可以简化EOF 的测试,例如
fputs (PROMPT, stdout);
if ((nchr = getline (&line, &n, stdin)) == -1) {
putchar ('\n'); /* tidy up with newline */
break;
}
剩下的就是标记 line 并在适当的索引 (ndx) 处分配指向 myargv 的指针。您可以使用while 循环,但for 提供了一种使用strtok 进行标记的便捷方式,例如
for (char *p = strtok (line, DELIM); p; p = strtok (NULL, DELIM)) {
myargv[ndx] = p; /* points within line, duplicate as req'd */
printf ("token: %s\n", myargv[ndx++]);
if (ndx == BUFFERSIZE - 1) /* preserve sentinel NULL */
break;
}
/* call to execvp, etc. here */
(注意:只需将指向标记的指针分配给myargv[ndx],myargv[ndx] 就指向line 中字符串的位置。@987654360 时必须使用指针@ 仍在作用域内。否则,您需要为每个令牌分配内存,将新内存块的起始地址分配给myargv[ndx],并将令牌复制到新内存块。(malloc 和strcpy ,或者strdup,如果你有的话))
最后,不要忘记,getline 分配的,所以不要忘记 free() 当你完成分配的内存,例如
free (line); /* don't forget to free memory allocated by getline */
}
总而言之,您可以使用类似于以下内容的方式对您的行进行标记:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFERSIZE 256
#define PROMPT "myShell >> "
#define DELIM " \n"
int main (void) {
while (1) {
size_t ndx = 0, /* line index */
n = 0; /* line alloc size (0, getline decides) */
ssize_t nchr = 0; /* return (chars read by getline) */
char *line = NULL, /* buffer to read each line */
*myargv[BUFFERSIZE] = {NULL}; /* array of pointers - init NULL */
fputs (PROMPT, stdout);
if ((nchr = getline (&line, &n, stdin)) == -1) {
putchar ('\n'); /* tidy up with newline */
break;
}
for (char *p = strtok (line, DELIM); p; p = strtok (NULL, DELIM)) {
myargv[ndx] = p; /* points within line, duplicate as req'd */
printf ("token: %s\n", myargv[ndx++]);
if (ndx == BUFFERSIZE - 1) /* preserve sentinel NULL */
break;
}
/* call to execvp, etc. here */
free (line); /* don't forget to free memory allocated by getline */
}
return 0;
}
使用/输出示例
$ ./bin/getlinestrtok
myShell >> my dog has fleas
token: my
token: dog
token: has
token: fleas
myShell >> my cat has none
token: my
token: cat
token: has
token: none
myShell >> happy cat
token: happy
token: cat
myShell >>
检查一下,如果您还有其他问题,请告诉我。