2016-04-01 148 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