0

私は本当にまともなプログラマーだと断言しますが、何年にもわたってJavaでプログラミングした後のCプログラミングの冒険は私を怒らせています。

2 次元の char 配列に IP アドレスとポートのペアのセットを入力しようとしています。ファイルから読み込んでいます。それらはファイルから正しく引き出されており、アレイに正しく配置されているはずです。問題は、何らかの理由で 2 番目のセットが配列に配置されているときに、最初のセットが上書きされ、その理由が一生わからないことです。

ファイルの最初の行は、ファイル内の IP アドレス/ポートのペアの数です (私はそれらをタプルと呼びます)。次の行は、スペースで区切られた IP アドレスとポートです。

コードは次のとおりです。

 //read the top line with the number of items
  fgets(line, sizeof line, fp);
  numLines = atoi(line);
  printf("%s %d\n","numLines:",numLines);
  char* tuples[numLines][2];
  char* rawLines[numLines];
  //read each line and put it into array
  for(currentLine=0; currentLine<numLines; currentLine++){
    if(fgets(line, sizeof line, fp) == NULL){
      perror("fgets");
      return -1;
    }
    printf("%s %d \n","curentLine: ",currentLine);
    char* port;
    tuples[currentLine][0] = strtok(line, " ");
    printf("%s %s \n", "IP Address: ", tuples[currentLine][0]);
    //rawLines[currentLine] = line;
    port = strtok(NULL, " ");
    size_t ln = strlen(port) - 1;
    if (port[ln] == '\n')
      port[ln] = '\0';
    tuples[currentLine][1]=port;
    printf("%s %s\n","port: ", tuples[currentLine][1]);
  }
  //list created and stored in tuples
  //now that list is created choose a random server from the file and strip the value chosen from the list

  //choose random server
  srand (time(NULL));
  //randomServer = rand()%numLines;
  randomServer = 0;
  printf("%s %d\n", "randomServer: ", randomServer);



  //connect to random server pulled
  memset(&hints, 0, sizeof hints); // make sure the struct is empty
  hints.ai_family = AF_UNSPEC;     // don't care IPv4 or IPv6
  hints.ai_socktype = SOCK_STREAM; // TCP stream sockets
  hints.ai_flags = AI_PASSIVE;     // fill in my IP for me
  //setup client socket
  printf("%s %s \n", "Setting up connection to: ", tuples[randomeServer][0]);
  printf("%s %s \n", "Setting up connection on port: ", tuples[randomServer][1]);

これが私が得る出力です:

numLines: 2
curentLine:  0
IP Address:  127.0.0.1
port:  3761
curentLine:  1
IP Address:  192.168.0.1
port:  3762
randomServer:  0
Setting up connection to:  192.168.0.1
Setting up connection on port:  1

私が期待しているのは:

ファイルに 1 行しかない場合は、期待値が得られます。

前もって感謝します。

4

4 に答える 4

2

strtokreturn を二次元配列に直接代入する代わりに、内容をstrcpy次のようにコピーします。

char *ipAddress = strtok(line, " ");
char *tuple0 = malloc(sizeof(char) * (strlen(ipAddress) + 1));
strcpy(tuple0, ipAddress);
tuples[currentLine][0] = tuple0;
于 2013-10-09T19:49:02.987 に答える
0

問題は、データを正しくコピーしていないことです。lineの配列のように見えるという名前の変数がありchar、 を使用fgets()して入力の各行をこの変数に読み込みます。次に、入力をトークン化し、トークンごとに配列内の場所へのポインターをline配列tuplesに格納しますが、このデータは次の行を読み取るとすぐに上書きされます。実際に行う必要があるのは、新しいストレージを割り当て、そこにデータをコピーし、その新しいストレージへのポインターをtuples配列に格納することです。

于 2013-10-09T19:50:27.963 に答える
0

「保存された」文字列にメモリを割り当てていないようです。あなたの宣言:

char* tuples[numLines][2];
char* rawLines[numLines];

char へのポインターの配列を宣言します。「弦」ではありません。したがって、次のようなものが欠けています:

tuples[index_value][0] = malloc(number_of_characters); 

そして、そのメモリに読み込んだ行を strcpy または strncpy で書き込む必要があります。

sizeof(char) は常に 1 です

于 2013-10-09T19:51:02.477 に答える
0

C には 2D 配列がないことを覚えておく価値があります。2D 配列は、C で (少なくとも) 2 つの異なる具象構造で実装できる抽象的な概念です。配列の配列があり、ポインターの配列があります。

ポインターの配列について話しているとき、通常 (常にではありません) 個々のポインターがメモリの異なるチャンクを指すように配置し、抽象的な 2D 配列に同じ行の重複が含まれないようにします。これを行うには、通常、各行を明示的にヒープに割り当ててから、値を入力します。strtok何も割り当てないことに注意してください。文字配列を受け取り、その中を指すポインターを返します (そしてそこにあった元の文字列を破棄します)。

于 2013-10-09T20:16:08.430 に答える