为三个变量定界 Char 数组

Delimiting Char Array for Three Variables

我正在编写一个程序来将命令行参数解析为三个不同的部分:主机名文件路径文件名,但是我不确定如何解析单个命令行参数并将单独的部分存储在三个不同的变量中。

我需要每个部分在我的程序的客户端创建一个套接字。到目前为止,我已经能够解析 主机名 部分,但在那之后我就卡住了。

有没有办法在解析字符串的一部分后?

编辑: 我要解析的字符串类似于 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, "/");
    }
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

您可以使用 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

希望对您有所帮助。

当您知道分隔符时,永远不要忘记您可以使用简单的指针算法来 split/parse 任何刺痛。 strtoksscanf 是很好的工具,但您可以手动执行相同的操作。这是一个要添加到您的列表中的简短示例:

#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

已更新,以防止使用 p.

读取超出 line 末尾的可能性

您还可以使用 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);
}

访问主机数组元素,因为它将包含由“/”分隔的索引值