分段错误:从文本文件中读取值

时间:2022-11-19 13:31:38

In my code I am trying to read values from a .txt file so as to build my adjacency matrix but it keeps on returning a segmentation fault. I don't seem to be able to point out where I am going wrong. Please help.

在我的代码中,我试图从.txt文件读取值,以便构建我的邻接矩阵,但它继续返回分段错误。我似乎无法指出我哪里出错了。请帮忙。

#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <math.h>
#include <limits.h>
#include <iostream>


#define MAX_VERTICES 1024

int global_adj_matrix[MAX_VERTICES][MAX_VERTICES];


int **graph_tree;
int **node_data;
int global_weight;
int number_threads;
int max_nodes;
int random_node;
int max_weight;
int finish_flag;

void readAdjMatrix();


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

    for(int i = 0 ; i < MAX_VERTICES ; i++){
        for(int j = 0 ; j < MAX_VERTICES ; j++){
            global_adj_matrix[i][j] = 0;
        }
    }

    number_threads = atoi(argv[1]);
    max_nodes = 0;

    readAdjMatrix();

}

void readAdjMatrix(){

    int source, destination, edge_weight;

    max_nodes = INT_MIN;
    max_weight = INT_MIN;

    FILE *file_pointer = fopen("graph.txt", "r");

    while(!feof(file_pointer)){
        fscanf(file_pointer, "%d", &source);
        fscanf(file_pointer, "%d", &destination);
        fscanf(file_pointer, "%d", &edge_weight);

        global_adj_matrix[source][destination] = edge_weight;
        global_adj_matrix[destination][source] = edge_weight;

        if(edge_weight > max_weight)
            max_weight = edge_weight;

        if(destination > max_nodes)
            max_nodes = destination;
    }

    printf("%d %d", max_weight, max_nodes);

    for(int i = 0 ; i <= max_nodes ; i++){
        for(int j = 0 ; j <= max_nodes ; j++){
            printf("%d\t", global_adj_matrix[i][j]);
        }
        printf("\n");
    }

    fclose(file_pointer);
}

This is my .txt file

这是我的.txt文件

0 1 281
0 2 242
0 3 344
0 4 340
0 5 372
0 6 161
0 7 49
0 8 278
0 10 190
0 11 213
0 12 55
0 13 239
0 14 321
0 15 162
1 0 281
1 2 249
1 3 58
1 4 331
1 5 189
1 6 84
1 7 259
1 9 256
1 11 188
1 12 149
1 13 330
1 14 17
1 15 370
2 0 242
2 1 249
2 3 125
2 4 179
2 5 355
2 6 11
2 7 232
2 8 199
2 9 67
2 10 390
2 12 312
2 13 3
2 14 237
2 15 96
3 0 344
3 1 58
3 2 125
3 4 105
3 5 192
3 6 180
3 7 335
3 8 280
3 9 185
3 10 66
3 11 65
3 13 274
3 14 72
3 15 282
4 0 340
4 1 331
4 2 179
4 3 105
4 5 149
4 6 286
4 7 265
4 8 359
4 9 341
4 10 211
4 11 367
4 12 340
4 13 14
4 14 69
4 15 128
5 0 372
5 1 189
5 2 355
5 3 192
5 4 149
5 6 167
5 7 268
5 8 20
5 9 270
5 10 210
5 11 369
5 12 131
5 13 133
5 15 167
6 0 161
6 1 84
6 2 11
6 3 180
6 4 286
6 5 167
6 7 208
6 8 335
6 9 353
6 10 12
6 11 307
6 12 199
6 13 273
6 14 118
7 0 49
7 1 259
7 2 232
7 3 335
7 4 265
7 5 268
7 6 208
7 8 182
7 9 327
7 10 272
7 11 198
7 12 103
7 13 132
7 15 161
8 0 278
8 2 199
8 3 280
8 4 359
8 5 20
8 6 335
8 7 182
8 9 108
8 10 112
8 11 344
8 12 192
8 13 264
8 14 207
8 15 231
9 1 256
9 2 67
9 3 185
9 4 341
9 5 270
9 6 353
9 7 327
9 8 108
9 10 395
9 11 205
9 12 365
9 13 8
9 14 57
9 15 132
10 0 190
10 2 390
10 3 66
10 4 211
10 5 210
10 6 12
10 7 272
10 8 112
10 9 395
10 11 11
10 12 7
10 13 288
10 14 143
10 15 226
11 0 213
11 1 188
11 3 65
11 4 367
11 5 369
11 6 307
11 7 198
11 8 344
11 9 205
11 10 11
11 12 203
11 13 136
11 14 252
11 15 168
12 0 55
12 1 149
12 2 312
12 4 340
12 5 131
12 6 199
12 7 103
12 8 192
12 9 365
12 10 7
12 11 203
12 13 90
12 14 344
12 15 11
13 0 239
13 1 330
13 2 3
13 3 274
13 4 14
13 5 133
13 6 273
13 7 132
13 8 264
13 9 8
13 10 288
13 11 136
13 12 90
13 14 39
13 15 39
14 0 321
14 1 17
14 2 237
14 3 72
14 4 69
14 6 118
14 8 207
14 9 57
14 10 143
14 11 252
14 12 344
14 13 39
14 15 154
15 0 162
15 1 370
15 2 96
15 3 282
15 4 128
15 5 167
15 7 161
15 8 231
15 9 132
15 10 226
15 11 168
15 12 11
15 13 39
15 14 154

2 个解决方案

#1


3  

Your segmentation fault is because you're trying to read a nonexistent index in the argument vector of main. If you want to avoid that, you should rewrite it to match something like this:

您的分段错误是因为您尝试在main的参数向量中读取不存在的索引。如果你想避免这种情况,你应该重写它以匹配这样的东西:

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

    if (argc > 1 && (number_threads = atoi(argv[1]))) {
        max_nodes = 0;
        readAdjMatrix();
    }

    return 0;
}

This ensures that you have an argument to convert to begin with, and also that it is a nonzero number. I believe atoi has undefined behavior if it isn't a valid string though, so you should harden against that. You also do some other unnecessary things. For one, this block here:

这可以确保您有一个转换为begin的参数,并且它还是一个非零数字。我相信如果它不是一个有效的字符串,atoi有未定义的行为,所以你应该坚持这一点。你还做了一些其他不必要的事情。首先,这个块在这里:

   for(int i = 0 ; i < MAX_VERTICES ; i++){
        for(int j = 0 ; j < MAX_VERTICES ; j++){
            global_adj_matrix[i][j] = 0;
        }
    }

is pointless because if you initialize a 2D array as an external/global variable then it is automatically zeroed upon initialization. Only local/automatic variables will be filled with garbage data. Therefore, you can omit it.

没有意义,因为如果将2D数组初始化为外部/全局变量,则在初始化时会自动归零。只有本地/自动变量将填充垃圾数据。因此,您可以省略它。

Finally, I would also change your while loop to look more or less like this (Credit: Chux for better loop guard).

最后,我还会改变你的while循环看起来或多或少像这样(Credit:Chux以获得更好的循环防护)。

while(fscanf(file_pointer, "%d %d %d", &source, &destination, &edge_weight) == 3) {

    global_adj_matrix[source][destination] = global_adj_matrix[destination][source] = edge_weight;

    if(edge_weight > max_weight)
        max_weight = edge_weight;

    if(destination > max_nodes)
        max_nodes = destination;
}

This ensures you correctly scanned the amount of variables necessary per line. And the extended assignment just saves a bit of room.

这可确保您正确扫描每行所需的变量数量。扩展的任务只是节省了一点空间。

Hope this fixed the problem you were having.

希望这能解决你遇到的问题。

#2


0  

I am posting my answer by neglecting the bigger code which you have not mentioned in your question. I have trimmed down the unnecessary code. The code is given below.

我通过忽略你在问题中没有提到的更大的代码来发布我的答案。我已经删除了不必要的代码。代码如下。

 #include <stdio.h>
 #include <unistd.h>
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
 #include <math.h>
 #include <limits.h>

 #define MAX_VERTICES 1024

 int global_adj_matrix[MAX_VERTICES][MAX_VERTICES];
 int global_weight,max_nodes,random_node,max_weight;

 void readAdjMatrix();


 int main()
 {
  int i,j;

   max_nodes = 0;
   readAdjMatrix();
   return 0;
 }


 void readAdjMatrix()
 {
  int source, destination, edge_weight,i,j;
  max_nodes = INT_MIN;
  max_weight = INT_MIN;

  FILE *file_pointer = fopen("graph.txt", "r");

  while(!feof(file_pointer))
  {
    fscanf(file_pointer, "%d", &source);
    fscanf(file_pointer, "%d", &destination);
    fscanf(file_pointer, "%d", &edge_weight);

    global_adj_matrix[source][destination] = global_adj_matrix[destination][source] =edge_weight;


    if(destination > max_nodes)
        max_nodes = destination;
   }

   printf( "%d\n", max_nodes);

   for( i = 0 ; i <= max_nodes ; i++){
    for( j = 0 ; j <= max_nodes ; j++){
        printf("%d\t", global_adj_matrix[i][j]);
    }
    printf("\n");
   }

   fclose(file_pointer);
  }

PS : Simply execute this code with ./a.out with no command line argument. In case you are using the command line argument (as given in your question), please use the following syntax to execute your code :

PS:只需使用./a.out执行此代码,不使用命令行参数。如果您使用的是命令行参数(如问题中所示),请使用以下语法执行代码:

./a.out "your desired number which works with the bigger code"

./a.out“您想要的数字与更大的代码一起使用”

#1


3  

Your segmentation fault is because you're trying to read a nonexistent index in the argument vector of main. If you want to avoid that, you should rewrite it to match something like this:

您的分段错误是因为您尝试在main的参数向量中读取不存在的索引。如果你想避免这种情况,你应该重写它以匹配这样的东西:

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

    if (argc > 1 && (number_threads = atoi(argv[1]))) {
        max_nodes = 0;
        readAdjMatrix();
    }

    return 0;
}

This ensures that you have an argument to convert to begin with, and also that it is a nonzero number. I believe atoi has undefined behavior if it isn't a valid string though, so you should harden against that. You also do some other unnecessary things. For one, this block here:

这可以确保您有一个转换为begin的参数,并且它还是一个非零数字。我相信如果它不是一个有效的字符串,atoi有未定义的行为,所以你应该坚持这一点。你还做了一些其他不必要的事情。首先,这个块在这里:

   for(int i = 0 ; i < MAX_VERTICES ; i++){
        for(int j = 0 ; j < MAX_VERTICES ; j++){
            global_adj_matrix[i][j] = 0;
        }
    }

is pointless because if you initialize a 2D array as an external/global variable then it is automatically zeroed upon initialization. Only local/automatic variables will be filled with garbage data. Therefore, you can omit it.

没有意义,因为如果将2D数组初始化为外部/全局变量,则在初始化时会自动归零。只有本地/自动变量将填充垃圾数据。因此,您可以省略它。

Finally, I would also change your while loop to look more or less like this (Credit: Chux for better loop guard).

最后,我还会改变你的while循环看起来或多或少像这样(Credit:Chux以获得更好的循环防护)。

while(fscanf(file_pointer, "%d %d %d", &source, &destination, &edge_weight) == 3) {

    global_adj_matrix[source][destination] = global_adj_matrix[destination][source] = edge_weight;

    if(edge_weight > max_weight)
        max_weight = edge_weight;

    if(destination > max_nodes)
        max_nodes = destination;
}

This ensures you correctly scanned the amount of variables necessary per line. And the extended assignment just saves a bit of room.

这可确保您正确扫描每行所需的变量数量。扩展的任务只是节省了一点空间。

Hope this fixed the problem you were having.

希望这能解决你遇到的问题。

#2


0  

I am posting my answer by neglecting the bigger code which you have not mentioned in your question. I have trimmed down the unnecessary code. The code is given below.

我通过忽略你在问题中没有提到的更大的代码来发布我的答案。我已经删除了不必要的代码。代码如下。

 #include <stdio.h>
 #include <unistd.h>
 #include <ctype.h>
 #include <string.h>
 #include <stdlib.h>
 #include <math.h>
 #include <limits.h>

 #define MAX_VERTICES 1024

 int global_adj_matrix[MAX_VERTICES][MAX_VERTICES];
 int global_weight,max_nodes,random_node,max_weight;

 void readAdjMatrix();


 int main()
 {
  int i,j;

   max_nodes = 0;
   readAdjMatrix();
   return 0;
 }


 void readAdjMatrix()
 {
  int source, destination, edge_weight,i,j;
  max_nodes = INT_MIN;
  max_weight = INT_MIN;

  FILE *file_pointer = fopen("graph.txt", "r");

  while(!feof(file_pointer))
  {
    fscanf(file_pointer, "%d", &source);
    fscanf(file_pointer, "%d", &destination);
    fscanf(file_pointer, "%d", &edge_weight);

    global_adj_matrix[source][destination] = global_adj_matrix[destination][source] =edge_weight;


    if(destination > max_nodes)
        max_nodes = destination;
   }

   printf( "%d\n", max_nodes);

   for( i = 0 ; i <= max_nodes ; i++){
    for( j = 0 ; j <= max_nodes ; j++){
        printf("%d\t", global_adj_matrix[i][j]);
    }
    printf("\n");
   }

   fclose(file_pointer);
  }

PS : Simply execute this code with ./a.out with no command line argument. In case you are using the command line argument (as given in your question), please use the following syntax to execute your code :

PS:只需使用./a.out执行此代码,不使用命令行参数。如果您使用的是命令行参数(如问题中所示),请使用以下语法执行代码:

./a.out "your desired number which works with the bigger code"

./a.out“您想要的数字与更大的代码一起使用”