Как перебрать переменную char ** - PullRequest
0 голосов
/ 30 апреля 2019

Я запускаю небольшую программу rpc / использую инфраструктуру rpc, которая берет char[] из файла клиента и отправляет его на сервер, который перечисляет целые числа в строке.

У меня есть файлclient.c, который принимает пользовательский ввод и передает его внешней функции в заголовочном файле.

#include <rpc/rpc.h>
#include "getNumInt.h"

int main(int argc, char **argv){
    CLIENT *cli;
    char *server;
    server = argv[1];

    cli = clnt_create(server, GETNUMINT, GNUMINT, "tcp"); //creates a client handle
    /*does some check for whether the client connected*/
    char command[256];
    int *numInt;
    fgets(command, 256, stdin); 
    numInt = enumints_1(&command, cli); //segfaults here according to backtrace
    return(0);
}

Функция enumints_1 определена в моей заглушке сервера server.c как:

int *enumints_1(msg, req)
    char **msg; struct svc_req *req;{
    printf(*msg);
    static int numDigits = 0;
    char msgcopy[256];
    strcpy(msgcopy, *msg);
    int i = 0;
    for(i; i<strlen(msgcopy); i++){
        if(msgcopy[i] >= '0' && msgcopy[i] <='9'){
            numDigits++;
        }
    }
    return(&numDigits);
}

Моя главная проблема заключается в том, как я выполняю итерацию по char **msg, поскольку это вероятнопочему моя программа segfaulting.command - это просто строка, взятая из пользовательского ввода, а затем переданная по ссылке в функцию enumints_1.Поскольку это указатель на точку, я предположил, что могу просто strcpy или memcpy скопировать строку в массив символов, но это не сработает.

также мой .x файл:

struct intStringPair{
    int numInts;
    char msg[256];
};

program GETNUMINT{
    version GNUMINT{
        int ENUMINTS(string) = 1; //string considered char * the rpc generated file makes it so enumints_1 then has to take char **
        int WRITEMESSAGE(intStringPair) = 2;
    } = 1;
}= 0x20000001;

1 Ответ

3 голосов
/ 30 апреля 2019

Как @ user3386109 сказал:

Команда не является указателем. Поэтому & команда не является указателем на указатель

поэтому назначение & command для msg недопустимо (а мой компилятор даже не компилирует)

Когда я компилирую этот код:

// my set up code

#include <stdio.h>
#include <string.h>
struct svc_req {};
typedef struct svc_req CLIENT;
struct svc_req *clnt_create(const char *, int, int, const char*) {return 0;}
int GETNUMINT=0, GNUMINT=0;

// your code verbatim

int *enumints_1(char **msg, struct svc_req *req){
    printf(*msg);
    static int numDigits = 0;
    char msgcopy[256];
    strcpy(msgcopy, *msg);
    int i = 0;
    for(i; i<strlen(msgcopy); i++){
        if(msgcopy[i] >= '0' && msgcopy[i] <='9'){
            numDigits++;
        }
    }
    return(&numDigits);
}

int main(int argc, char **argv){
    CLIENT *cli;
    char *server;
    server = argv[1];

    cli = clnt_create(server, GETNUMINT, GNUMINT, "tcp"); //creates a client handle
    /*does some check for whether the client connected*/
    char command[256];
    int *numInt;
    fgets(command, 256, stdin); 
    numInt = enumints_1(&command, cli); //segfaults here according to backtrace
    return(0);
}

Компилятор говорит:

<source>: In function 'int main(int, char**)':
<source>:34:25: error: cannot convert 'char (*)[256]' to 'char**'
     numInt = enumints_1(&command, cli); //segfaults here according to backtrace
                         ^~~~~~~~
<source>:10:24: note:   initializing argument 1 of 'int* enumints_1(char**, svc_req*)'
 int *enumints_1(char **msg, struct svc_req *req){
                 ~~~~~~~^~~
Compiler returned: 1

Вместо этого вы можете создать указатель на массив и затем передать его адрес:

// my set up code
#include <stdio.h>
#include <string.h>
struct svc_req {};
typedef struct svc_req CLIENT;
struct svc_req *clnt_create(const char *, int, int, const char*) {return 0;}
int GETNUMINT=0, GNUMINT=0;

// your code verbatim
int *enumints_1(char **msg, struct svc_req *req){
    printf(*msg);
    static int numDigits = 0;
    char msgcopy[256];
    strcpy(msgcopy, *msg);
    int i = 0;
    for(i; i<strlen(msgcopy); i++){
        if(msgcopy[i] >= '0' && msgcopy[i] <='9'){
            numDigits++;
        }
    }
    return(&numDigits);
}

int main(int argc, char **argv){
    CLIENT *cli;
    char *server;
    server = argv[1];

    cli = clnt_create(server, GETNUMINT, GNUMINT, "tcp"); //creates a client handle
    /*does some check for whether the client connected*/
    char command[256], *command_pointer=command;
    int *numInt;
    fgets(command, 256, stdin); 
    numInt = enumints_1(&command_pointer, cli); //segfaults here according to backtrace
    return(0);
}
...