2016-04-01 117 views
1

我在为旅行推销员问题正确打印2D数组时遇到问题。我使用输入重定向从文本文件获取输入。该文件包含城市和城市之间的距离的弧线。这是一个小例子。2D Array错误地打印

c 1 
c 2 
a 1 2 1400 

设置我的数组和策划我使用嵌套了城市之间的距离for循环打印出数组,但它看起来像在此之后。

0  1  2  3  4  5 

    1  0  1400 1800 4000 3500 

    2  1  0  0  3400 3600 

    3  1800 1200 0  2300 0 

    4  4000 3400 2300 0  2100 

    5  3500 3600 0  2100 0 

编辑:我想使它看起来像这样

0  1  2  3  4  5 

    1  0  1400 1800 4000 3500 

    2  1400 0  1200 3400 3600 

    3  1800 1200 0  2300 2700 

    4  4000 3400 2300 0  2100 

    5  3500 3600 2700 2100 0 

我试图操纵for循环不同的方式,但我似乎无法揣摩出我的问题是在循环或者这是我的代码中的其他地方。

// Sets up the array 
int CityArray [6][6] = { {0, 0, 0, 0, 0, 0}, 
         {0, 0, 0, 0, 0, 0}, 
         {0, 0, 0, 0, 0, 0}, 
         {0, 0, 0, 0, 0, 0}, 
         {0, 0, 0, 0, 0, 0}, 
         {0, 0, 0, 0, 0, 0} 
         }; 

int main(void) // Takes in a variable number of arguments 
{ 
    // Sets a string input for the city 
    char Cbuffer[32]; 
    char *b = Cbuffer; 
    size_t cbufsize = 32; 
    size_t cinput; 

    // Other vairables 
    int x = 1; // used to go through the array 
    int n1, n2, n3, n4, cost; // variables to store the value pulled the cost from the arc 

    // Reads in the city and sets the prices for each arc 
    while((cinput = getline(&b, &cbufsize, stdin)) != -1) 
    { 
     if (Cbuffer[0] == 'c') 
     { 
      // Stores the last element as a digit to CityArray 
      if (Cbuffer[2] >= '0' && Cbuffer[2] <= '9') 
      { 
       CityArray[x][0] = Cbuffer[2] - '0'; 
       int z = CityArray[x][0]; 
       // Flips it 
       CityArray[0][x] = Cbuffer[2] - '0'; 
       z = CityArray[0][x]; 
       // printf("CityArray[%d] is '%d' \n", x, z); 
       x++; 
      } 
     } 
     else if (Cbuffer[0] == 'a') 
     { 
      int y = 1; 
      // I know this looks ugly but it's the only way I could think of getting the prices 
      if ((Cbuffer[6] >= '0' && Cbuffer[6] <= '9') && (Cbuffer[7] >= '0' && Cbuffer[7] <= '9') && 
        (Cbuffer[8] >= '0' && Cbuffer[8] <= '9') && (Cbuffer[9] >= '0' && Cbuffer[9] <= '9')) 
      { 
       for (x = 1; x < 6; x++) 
       { 
        for (y; y < 6; y++) 
        { // converts the char to a int 
         n1 = CityArray[x][6] = Cbuffer[6] - '0'; 
         n2 = CityArray[x][7] = Cbuffer[7] - '0'; 
         n3 = CityArray[x][8] = Cbuffer[8] - '0'; 
         n4 = CityArray[x][9] = Cbuffer[9] - '0'; 
        } 
       } // sets all converted ints to = cost 
       cost = (n1 * 1000) + (n2 * 100) + (n3 * 10) + (n4 * 1); 
       x++; 
      } 
      // Checks where the arc is located and plots the distance of the trip 
      if (Cbuffer[2] == '1') 
      { 
       if (Cbuffer[4] == '2') 
       { 
        CityArray[1][2] = cost; 
        CityArray[2][1] = cost; 
       } 
       else if (Cbuffer[4] == '3') 
       { 
        CityArray[1][3] = cost; 
        CityArray[3][1] = cost; 
       } 
       else if (Cbuffer[4] == '4') 
       { 
        CityArray[1][4] = cost; 
        CityArray[4][1] = cost; 
       } 
       else if (Cbuffer[4] == '5') 
       { 
        CityArray[1][5] = cost; 
        CityArray[5][1] = cost; 
       } 
      } 
      else if (Cbuffer[2] == '2') 
      { 
       if (Cbuffer[4] == '3') 
       { 
        CityArray[2][3] = cost; 
        CityArray[3][2] = cost; 
       } 
       else if (Cbuffer[4] == '4') 
       { 
        CityArray[2][4] = cost; 
        CityArray[4][2] = cost; 
       } 
       else if (Cbuffer[4] == '5') 
       { 
        CityArray[2][5] = cost; 
        CityArray[5][2] = cost; 
       } 
      } 
      else if (Cbuffer[2] == '3') 
      { 
       if (Cbuffer[4] == '4') 
       { 
        CityArray[3][4] = cost; 
        CityArray[4][3] = cost; 
       } 
      else if (Cbuffer[4] == '5') 
      { 
        CityArray[4][5] = cost; 
        CityArray[5][4] = cost; 
       } 
      } 
      else if (Cbuffer[2] == '4') 
      { 
       if (Cbuffer[4] == '5') 
       { 
        CityArray[4][5] = cost; 
        CityArray[5][4] = cost; 
       } 
      } 
     } 
    } 

    // Prints the array 
    int i, j; 
    printf("\n\nThe cost list is:\n\n"); 
    for(i = 0; i < 6;i ++) 
    { 
     printf("\n\n"); 
     for(j = 0; j < 6; j++) 
     { 
      printf("\t%d", CityArray[i][j]); 
     } 
     printf("\n"); 
    } 

    return 0; 
} 
+0

“但它看起来像这样。” - 你也可以解释你期望它看起来如何 –

+0

会让我编辑我的问题! – Cheezdue

+1

如果缓冲区不够大,getline将释放现有的缓冲区并分配一个新的缓冲区并返回。所以你不应该通过'Cbuffer',因为这是一个错误来释放它;你不应该测试'Cbuffer [0] =='c''等等,因为该行可能已经被重新分配。相反,你可以设置'b = NULL'来启动,并使用'b [0]'等等(或者避免大量输入,摆脱'b'并使用'char * Cbuffer = NULL;')。 [可能与你的问题没有关系,因为你的文件行数都小于32,但是这是一个滴答作响的时间炸弹] –

回答

1

你的问题是在这里:

  for (x = 1; x < 6; x++) 
      { 
       for (y; y < 6; y++) 
       { // converts the char to a int 
        n1 = CityArray[x][6] = Cbuffer[6] - '0'; 
        n2 = CityArray[x][7] = Cbuffer[7] - '0'; 
        n3 = CityArray[x][8] = Cbuffer[8] - '0'; 
        n4 = CityArray[x][9] = Cbuffer[9] - '0'; 
       } 
      } // sets all converted ints to = cost 
      cost = (n1 * 1000) + (n2 * 100) + (n3 * 10) + (n4 * 1); 
      x++; 

首先,你并不需要在这里循环;在这里循环意味着你会多次进行转换。 (更糟糕的是,因为你没有初始化y,你可能根本不会做这个转换,如果你激活了警告,你会得到一些独立的y的“声明无效”)

其次,您将转换后的数字存储在CityArray[x][6 ... 9]中,但指数为6以及超出范围。这是未定义的行为。实际上,您会覆盖下一个城市的数据。

第三,您不应该使用x作为循环变量和变量来保存城市的数量。该循环将覆盖数据。 (但是,问题消失了,当你删除环。)

只要做到:

  n1 = Cbuffer[6] - '0'; 
      n2 = Cbuffer[7] - '0'; 
      n3 = Cbuffer[8] - '0'; 
      n4 = Cbuffer[9] - '0'; 

      cost = (n1 * 1000) + (n2 * 100) + (n3 * 10) + (n4 * 1); 

的代码仍然存在诸多问题。特别是对城市和距离的分析非常有限。如果城市的成本不是四位数字,会发生什么?如果第一个城市的人数多于第二个城市,会发生什么?

您也可以使用从ASCII转换为单位整数的城市:

 int from = Cbuffer[2] - '0'; 
     int dest = Cbuffer[4] - '0'; 

     CityArray[from][dest] = cost; 
     CityArray[dest][from] = cost; 

这将摆脱大量的代码。与其对所有可能性进行硬编码,不如将您的精力用于编写有意义的错误消息,例如,如果某个城市的身份标识超出范围。

您还应该考虑使用标准方法来解析输入。 getline结合scanf可能是一个好方法。

编辑:以下是输入的示例实现。它最多可以采用10个城市,由一个可能是数字的单个字符标识。它对ca行的确切格式没有任何限制,并且还跟踪变量ncitiy中实际城市的数量。它接受以#作为非命令开头的空白行和行。

尽管错误检查很严重,但该程序比您的要短一些。这里有:

#define _GNU_SOURCE 

#include <stdlib.h> 
#include <stdio.h> 

#define MAX 10 


int find(int array[], int n, int x) 
{ 
    for (int i = 0; i < n; i++) { 
     if (array[i] == x) return i; 
    } 

    return -1; 
} 

int main(void) 
{ 
    int cost[10][10] = {{0}};  // cost matrix 
    int id[MAX];     // city id; can be any character 
    int ncity = 0;     // number of cities 

    char *line = NULL; 
    size_t nline = 0; 
    int error = 0; 

    while (getline(&line, &nline, stdin) != -1) { 
     char c1, c2; 
     int c; 

     if (sscanf(line, " c %c", &c1) == 1) { 
      if (find(id, ncity, c1) != -1) { 
       fprintf(stderr, "Duplicate city id %c.\n", c1); 
       error = 1; 
       break; 
      } else if (ncity >= MAX) { 
       fprintf(stderr, "Maximum number of cities exceeded\n"); 
       error = 1; 
       break; 
      } else { 
       id[ncity++] = c1; 
      } 
      continue; 
     } 

     if (sscanf(line, " a %c %c %d\n", &c1, &c2, &c) == 3) { 
      int from = find(id, ncity, c1); 
      int dest = find(id, ncity, c2); 

      if (from < 0) { 
       fprintf(stderr, "Unknown city id %c.\n", c1); 
       error = 1; 
       break; 
      } 

      if (dest < 0) { 
       fprintf(stderr, "Unknown city id %c.\n", c2); 
       error = 1; 
       break; 
      } 

      cost[from][dest] = c; 
      cost[dest][from] = c; 

      continue; 
     } 

     if (sscanf(line, " %c", &c1) == 1 && c1 != '#') { 
      fprintf(stderr, "Unknown command: %s", line); 
      error = 1; 
      break; 
     } 
    } 

    free(line); 

    if (error) { 
     fprintf(stderr, "Errors in input. Aborting.\n"); 
     exit(1); 
    } 

    printf("%8s", ""); 
    for (int j = 0; j < ncity; j++) { 
     printf("%8c", id[j]); 
    } 
    puts(""); 

    for(int i = 0; i < ncity; i ++) 
    { 
     printf("%8c", id[i]); 
     for (int j = 0; j < ncity; j++) { 
      printf("%8d", cost[i][j]); 
     } 
     puts(""); 
    } 
    puts(""); 

    return 0; 
} 
+0

谢谢,你的建议奏效了!最初我在想我的问题在我的代码的那一部分撒谎,但我没有意识到为什么它会导致我的问题。我知道我在城市阅读的方法非常有限,但我找不出一个更好的方法。您提供的代码是在城市阅读的好方法! – Cheezdue