Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 三个变量的字符数组定界_C_Sockets_Client Side - Fatal编程技术网

C 三个变量的字符数组定界

C 三个变量的字符数组定界,c,sockets,client-side,C,Sockets,Client Side,我正在编写一个程序,将命令行参数解析为三个不同的部分:主机名、文件路径和文件名,但是我不确定如何解析单个命令行参数并将单独的部分存储在三个不同的变量中 我需要每个部分在程序的客户端上创建一个套接字。到目前为止,我已经能够解析主机名部分,但在那之后我就被卡住了 在解析了字符串的一部分之后,有没有一种方法可以 编辑: 我试图解析的字符串类似于camelot.cba.csuohio.edu/~yourloginid/filename.txt 这是我的密码 #include <stdio.h>

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

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

在解析了字符串的一部分之后,有没有一种方法可以

编辑: 我试图解析的字符串类似于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;
} 
你可以用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);
}
我没有编译它,但我希望你可以用它作为一个例子

这里有一个完整的例子说明如何使用它

希望这有帮助。

你可以用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);
}
我没有编译它,但我希望你可以用它作为一个例子

这里有一个完整的例子说明如何使用它


希望这有帮助。

当您知道分隔符时,千万不要忘记您有简单的指针算法可用于拆分/解析任何sting。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;
}

更新以防止可能的读取超出行尾p.

当您知道分隔符时,千万不要忘记您有简单的指针算法可用于拆分/分析任何sting。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;
}

更新以防止可能的读取超出p的行尾。

您也可以使用strtok\u 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);
}

访问主机数组元素,因为它将包含由/

分隔的索引值。由于strtok不是线程安全的,您还可以使用strtok\u r进行如下解析

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);
}

访问主机数组元素,因为它将包含由/

分隔的索引值。不要在这样的循环中使用strlen,它会在每次迭代时计算长度。相反,对于i=0,可以这样做;buf[i]!='\0'&buf[i]!='/'++i、 也不需要中断。你能提供一个示例输入吗?我刚刚为它添加了一个编辑。使用++i相对于i++有什么好处吗?++i表示增量i,然后进行计算。i++表示求值i,然后在求值后增加它。从for循环的角度来看,选择使用哪个循环应该没有什么区别。不要在这样的循环中使用strlen,它会计算每次迭代的长度。相反,对于i=0,可以这样做;buf[i]!='\0'&buf[i]!='/'++i、 也不需要中断。你能提供一个示例输入吗?我刚刚为它添加了一个编辑。使用++i相对于i++有什么好处吗?++i表示增量i,然后进行计算。i++表示求值i,然后在求值后增加它。从for循环的角度来看,选择使用哪一个不会有什么区别。我知道strtok,但我想知道如何使用它将一个字符串解析为三个。我为您的案例添加了一个示例。令牌在每次迭代中都有每个值。我知道strtok,但我想知道如何使用它将一个字符串解析为三个。我为您的案例添加了一个示例。令牌在每次迭代中都有每个值。是否有一种方法可以在每个令牌之后,将生成的字符串存储在一个临时变量中,以供以后处理?@Delfino使用strdup或类似方法复制strtok返回的令牌。如果我希望每个令牌都存储在不同的变量中,例如char host[]中的主机名、char path[]中的文件路径,该怎么办以及char fname[]中的文件名?是否有一种方法可以在每个令牌之后,将生成的字符串存储在一个临时变量中,以供以后处理?@Delfino使用strdup或类似方法复制strtok返回的令牌。如果我希望每个令牌都存储在不同的变量中,例如char host[]中的主机名、char path[]中的文件路径,该怎么办文件名是否为char fname[]?
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);
}