1

私は C の初心者ですが、最初にテキスト ファイルに保存された traceroute/tracert から取得した IP アドレスをユーザーが保存できるようにするプログラムを構築したいと考えていました。次に、次/前のホップを出力できるようにします。リンクされたリストを使用しましたが、印刷するとセグメンテーション エラーが発生します。

調べてみましたが、エラーが見つかりません。誰かが私のエラーを指摘して案内してくれますか? 前もって感謝します!!

(インデントが悪くてすみません!!)

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

int id = 0;
int list = 0;
int nodes = 0;

FILE *readFile(char *fileName)
{
  FILE *rawdata = fopen(fileName, "r");
  return rawdata;
}

void printMenu()
{
  printf(" ========== MENU =============\n\n");
  printf("1. Report ID of Previous Hops of a network node\n");
  printf("2. Identify the next hops of a network node\n");
  printf("3. Quit\n");
}

int getInput()
{
  int choice;
  printf("Please select your choice (1 to 3) =>: ");
  scanf("%d", &choice);
  return choice;
}

struct NodeInfo {
  int ID;
  int IP1;
  int IP2;
  int IP3;
  int IP4;
  struct NodeInfo *next;
  struct NodeInfo *prev;
};

typedef struct NodeInfo Node;
Node *Topology;

Node *createNode(int ip1, int ip2, int ip3, int ip4)
{
  Node *newNode = malloc(sizeof(Node));
  newNode->IP1 = ip1;
  newNode->IP2 = ip2;
  newNode->IP3 = ip3;
  newNode->IP4 = ip4;
  newNode->next = 0;            // NULL Pointer
  newNode->prev = 0;            // NULL Pointer
  return newNode;
}

void addToBack(Node * tempnode)
{
  Node *n = Topology;
  Node *tail = 0;
  while (n != NULL) {
    tail = n;
    n = n->next;
  }
  tail->next = tempnode;
  tempnode->prev = tail;
}


void printFile(FILE * newFile)
{

  char data[256], nth1[50], nth2[50], nth3[50], nth4[50], nth5[50],
      nth6[50], nth7[50], ip[50], ip2[15], ip2new[14];
  int linecount = -1, strlength;
  int ip1, ip2x, ip3, ip4;
  int ip11, ip21, ip31, ip41;

  if (newFile == NULL) {
    printf("There is an error with opening this file\n");
  } else {
    while (fgets(data, 256, newFile) != NULL) {

      if (linecount != 3) {
        linecount++;
        continue;
      } else {

        if (linecount == 3 && data[2] != '\0') {
          sscanf(data, "%s %s %s %s %s %s %s %s", nth1, nth2, nth3, nth4,
                 nth5, nth6, nth7, ip);
          sscanf(data, "%s %s %s %s %s %s %s %d.%d.%d.%d", nth1, nth2,
                 nth3, nth4, nth5, nth6, nth7, &ip1, &ip2x, &ip3, &ip4);

          if ((ip[0] <= 'z' && ip[0] >= 'a')
              || (ip[0] <= 'Z' && ip[0] >= 'A')) {
            sscanf(data, "%s %s %s %s %s %s %s %s %s",
                   nth1, nth2, nth3, nth4, nth5, nth6, nth7, ip, ip2);
            //Rescanning for anomaly results with additional hostname
            strncpy(ip2new, ip2 + 1, strlen(ip2) - 2);
            ip2new[strlen(ip2) - 2] = '\0';

            int i;
            char *temp;
            char *ipcmp[4];
            i = 0;
            temp = strtok(ip2new, ".");
            while (temp != NULL) {
              ipcmp[i++] = temp;
              temp = strtok(NULL, ".");
            }
            Node *tempnode = createNode(ip2new);
            if (Topology != 0) {
              addToBack(tempnode);
            } else {
              Topology = tempnode;
            }
          } else {
            printf("%s\n", ip);
            printf("%d.%d.%d.%d\n", ip1, ip2x, ip3, ip4);
            Node *tempnode2 = createNode(ip);
            if (Topology != 0) {
              addToBack(tempnode2);
            } else {
              Topology = tempnode2;
            }
            continue;
          }
        }
        if (linecount == 3 && data[2] == '\0') {
          linecount = -2;
          printf("\n");
        }
      }
    }
  }
}

void printNodes()
{
  Node *n = Topology;
  while (n != 0) {
    printf("The node is %d.%d.%d.%d\n", n->IP1, n->IP2, n->IP3, n->IP4);
    n = n->next;                // Jump to next node
  }
}

int main(int argc, char *argv[])
{

  int option, fail;
  FILE *filedata;
  char *file;
  file = argv[1];
  filedata = readFile(file);    //open file
  printFile(filedata);          //prints the ip addresses
  do {
    printMenu();
    option = getInput();
    switch (option) {
    case 1:
      printf("You have selected 1\n\n");
      fail = 0;
      printNodes();
      break;
    case 2:
      printf("You have selected 2\n\n");
      fail = 0;
      break;
    case 3:
      fail = 1;
      break;
    default:
      printf("Please enter a valid choice (1-3) \n");
      fail = 0;
      break;
    }
  } while (fail != 1);
  while (Topology != 0) {
    free(Topology);
    Topology = Topology->next;
  }
}
4

3 に答える 3

1

create node メソッドには 4 つのパラメーターがあります。

Node *createNode(int ip1, int ip2, int ip3, int ip4)

ただし、このメソッドを呼び出すには、パラメーターを 1 つだけ渡します。

Node *tempnode = createNode(ip2new);
Node *tempnode2 = createNode(ip);

また、メソッドが整数のみを受け入れる場合は、配列を渡します。

これは、コード内のエラーの少なくとも 2 つの原因です。

于 2013-08-13T01:36:58.600 に答える
1

私が見つけることができる2つの修正があります。createNode()まず、間違った数の引数で呼び出していることです。4 つの整数引数を取るように定義createNode()しましたが、呼び出しごとに文字列引数を渡しています。コンパイラは、この問題に関する診断を提供する必要があります (私のコンパイラはコードのコンパイルを拒否します)。コンパイラの診断を無視するべきではありません (少なくとも、最初に診断の意味を完全に理解するまでは)。

これらの呼び出しを変更して、スキャンした 4 つの整数変数を使用します。

            Node *tempnode = createNode(ip1, ip2x, ip3, ip4);

            Node *tempnode2 = createNode(ip1, ip2x, ip3, ip4);

2 番目のエラーは、が 3 に等しいif (linecount != 3) {場合にのみデータを処理できることですlinecount。これはおそらくやりたいことではありません。おそらく、linecount3 になった後にすべてのデータ行を処理することを意味します。

      if (linecount < 3) {
        linecount++;
        continue;
      } else {

linecountに初期化したのは奇妙だと思いますが-1、それは入力の 4 行目に到達するまでファイルの処理を開始しないことを意味します。

他の人が述べたように、すでに解放されているメモリから読み取ることはできません。これを行うと、未定義の動作が発生します。によって保持されているメモリを解放するループでTopology、現在のアイテムを解放する前に、次のアイテムへのポインターを保存します。

  while (Topology != 0) {
    void *cur = Topology;
    Topology = Topology->next;
    free(cur);
  }
于 2013-08-13T01:40:28.993 に答える
0

ここにはいくつかの問題があります。

  1. NULLとの使用法を混在させます0。どちらも機能しますが、C では を使用するのが慣用的でNULLあり、一貫した使用方法を使用するのが最善です。

  2. createNode関数は 4 つの整数を想定していますが、コードはこの関数を呼び出しており、引数を 1 つしか提供していません。

  3. ループに未定義の動作があります:

    while (Topology != 0) {
        free(Topology);
        Topology = Topology->next;
    }
    

    Topology解放された後にアクセスするのは未定義の動作です。あなたの場合、解放されたnextにメンバーにアクセスしようとしています。Topology

于 2013-08-13T01:46:15.400 に答える