我正在编写一个程序来将命令行参数解析为三个不同的部分:主机名,文件路径和文件名< / em>,但我不确定如何解析单个命令行参数并将单独的部分存储在三个不同的变量中。
我需要每个部分在我的程序的客户端创建一个套接字。到目前为止,我已经能够解析主机名部分了,但之后我就陷入了困境。
解析一部分字符串之后有没有办法?
编辑:
我尝试解析的字符串类似于camelot.cba.csuohio.edu/~yourloginid/filename.txt
这是我的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
int i, sk;
char buf[256], temp[256];
struct sockaddr_in remote;
struct hostent *hp;
if(argc != 2)
{
printf("Invalid number of arguments. Program terminating...");
exit(1);
}
sk = socket(AF_INET, SOCK_STREAM, 0);
remote.sin_family = AF_INET;
strcpy(buf, argv[1]);
for(i = 0; i < strlen(buf); i++)
{
if(buf[i] == '/')
break;
temp[i] = buf[i];
}
hp = gethostbyname(temp);
return 0;
}
编辑:
我实现了while
循环来实现我想要的东西,但我觉得它很草率。有没有办法可以改进它?
while(tk != NULL)
{
if(c == 0)
strcpy(host, tk);
else if(c == 1)
strcpy(path, tk);
else
strcpy(fname, tk);
c++;
tk = strtok(NULL, "/");
}
答案 0 :(得分:1)
char st[] = "camelot.cba.csuohio.edu/~yourloginid/filename.txt";
char *host, *path, *fname;
char *ch[3];
for (int i=0; i < 3; ++i) {
ch[i] = strtok(st, "/");
(if ch[i] == NULL) break;
printf("%s\n", ch[i]);
}
if (ch[0] != NULL) {
host = ch[0];
}
if (ch[1] != NULL) {
path = ch[1];
}
if (ch[2] != null) {
path = ch[2];
}
<强>输出:强>
camelot.cba.csuohio.edu
~yourloginid
filename.txt
答案 1 :(得分:1)
您可以使用strtok
一个粗略的例子就是
const char s[2] = "/";
char *token;
/* get the first token */
token = strtok(argv[1], s);
/* walk through other tokens */
while( token != NULL )
{
printf( " %s\n", token );
token = strtok(NULL, s);
}
我没有编译它,但我希望你可以用它作为例子。
这里有一个如何使用它的完整示例 http://www.tutorialspoint.com/c_standard_library/c_function_strtok.htm
希望这有帮助。
答案 2 :(得分:1)
当您知道分隔符时,永远不要忘记您可以使用简单的指针算法来分割/解析任何刺痛。 strtok
和sscanf
是很好的工具,但您可以手动执行相同的操作。以下是添加到列表中的简短示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXS 128
int main (int argc, char **argv) {
if (argc < 2 ) {
fprintf (stderr, "Error: insufficient input, usage: %s host,path,file\n", argv[0]);
return 1;
}
char *line = strdup (argv[1]); /* make a copy of argument string */
if (!line) {
fprintf (stderr, "error: strdup memory allocation/copy failed.\n");
return 1;
}
char *p = line; /* pointer to the argument string */
char *sp = NULL; /* pointer to use as start pointer */
char host[MAXS] = {0}; /* variables to hold tokens */
char path[MAXS] = {0};
char file[MAXS] = {0};
while (*p && *p != ',') p++; /* find the first ',' */
*p++ = 0; /* null-terminate, advance pointer */
strcpy (host, line); /* read/copy host name */
sp = p; /* set start pointer at current pos */
while (*p && *p != ',') p++; /* find next ',' */
*p++ = 0; /* null-terminate, advance pointer */
strcpy (path, sp); /* read/copy path */
strcpy (file, p); /* pointer on file, read/copy file */
printf ("\n host: %s\n path: %s\n file: %s\n\n", host, path, file);
free (line); /* free memory allocate by strdup */
return 0;
}
<强>输出强>
$ ./bin/split_host_path_file hostname,pathname,filename
host: hostname
path: pathname
file: filename
已更新以防止line
p
之后的潜在阅读超出{{1}}。
答案 3 :(得分:1)
你也可以用strtok_r解析如下,因为strtok不是线程安全的。
const char *delim="/";
char *str, *savePtr;
char hosts[3][32];
int i;
for(i=0,str=strtok_r(argv[1], delim, &savePtr);(str!=NULL);str=strtok_r(NULL, delim, &savePtr), i++)
{
print("%s\n", str);
strcpy((char *)host[i], (const char *)str);
}
访问主机数组元素,因为它将包含由&#34; /&#34;
分隔的索引值