Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.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 - Fatal编程技术网

C 二维字符数组问题

C 二维字符数组问题,c,C,我发誓我真的是一个不错的程序员,但是在用Java编程多年之后,我在C编程方面的冒险经历让我发疯 我试图用一组IP地址/端口对填充二维字符数组。我正在从文件中读取它们。它们被正确地从文件中拉出,并且应该被正确地放入数组中。问题是,由于某种原因,当第二个集合被放入数组时,它会覆盖第一个集合,而我一辈子都不知道为什么 文件的第一行是文件中IP地址/端口对的数量(我称之为元组)。以下几行是用空格分隔的IP地址和端口 代码如下: //read the top line with the number o

我发誓我真的是一个不错的程序员,但是在用Java编程多年之后,我在C编程方面的冒险经历让我发疯

我试图用一组IP地址/端口对填充二维字符数组。我正在从文件中读取它们。它们被正确地从文件中拉出,并且应该被正确地放入数组中。问题是,由于某种原因,当第二个集合被放入数组时,它会覆盖第一个集合,而我一辈子都不知道为什么

文件的第一行是文件中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]);
我希望得到的是: 设置到的连接:127.0.0.1 正在端口上设置连接:3761

如果文件中只有一行,则得到预期值


提前谢谢。

请使用
strcpy
复制内容,而不是直接分配
strtok
返回二维数组:

char *ipAddress = strtok(line, " ");
char *tuple0 = malloc(sizeof(char) * (strlen(ipAddress) + 1));
strcpy(tuple0, ipAddress);
tuples[currentLine][0] = tuple0;

问题是您没有正确复制数据。您有一个名为
line
的变量,它似乎是一个
char
数组,您可以使用
fgets()
将每一行输入读取到此变量中。然后将输入标记化,对于每个标记,将指针存储到
数组中,指向
元组
数组中的某个位置,但一旦在下一行中读取,该数据就会被覆盖。您真正需要做的是分配一个新的存储区,将数据复制到该存储区,并将指向该新存储区的指针存储到
元组数组中。

似乎您没有为“保存的”字符串分配内存。你的声明:

char* tuples[numLines][2];
char* rawLines[numLines];
声明指向char的指针数组。不是“字符串”。因此,您缺少以下内容:

tuples[index_value][0] = malloc(number_of_characters); 
然后你应该用strcpy或者strncpy写下你在内存中读到的行


值得记住的是,C语言中没有2D数组。2D数组是一个抽象概念,可以用(至少)两种不同的具体构造在C语言中实现。有数组的数组,也有指针的数组


当我们谈论指针数组时,我们通常(并非总是)安排它们,使单个指针指向不同的内存块,以免我们的抽象2D数组最终包含同一行的重复项。为了实现这一点,我们通常在堆上显式地分配每一行,然后用值填充它。请注意,
strtok
不分配任何内容。它接受一个字符数组并返回指向该数组的指针(并销毁其中的原始字符串)。

似乎是将指针分配给一个数组的典型症状,该数组的内容稍后会发生变化。除此之外:1。感谢您使用
fgets()
而不是脑死的
scanf()
(出于某种原因,每个人都喜欢(ab)使用它),2。但是为什么
printf(“%s%d\n”,“numLines:”,numLines)?更可读的版本是printf(“numLines:%d\n”,numLines)。此外,
strtol()
优于
atoi()
。它不应该是
sizeof(line)
?@John不,为什么
line
是一个对象,而不是一种类型。也许
strcpy
可以解决您的问题?@H2CO3您如何判断它不是一个字符数组?
sizeof(char)
始终是一个。关于这一点,需要注意几点:malloc调用需要空终止符+1。如果您
strcpy
“abc”,则需要4个字节。其次,不需要strcat
。strcpy已经为null终止结果(如果没有,则
strcat
将不起作用,因为它需要以null终止的目标开始:)。
tuples[index_value][0] = malloc(number_of_characters);