我正在处理一种必须用C解析的文件格式,如下所示:
5 3 1 3
1 4
1 5
3 2 3
2 4
2 5
2 3 1
3 2
3 4 1
4 2
4 5
3 5 1
5 2
5 4
除了第一行,它告诉我们顶点的数量,每一行有一个数字,表示有两个数字的行数。在这两个数字线上,我们可以看到两个顶点ID,它们是在一个图中连接的。我的目标是获取这些信息并将int转换成一个图。我编写了以下函数来读取单个顶点:
graph_vertex_t* read_vertex(FILE *fp, graph_vertex_t *last_vertex)
{
graph_vertex_t *current_vertex;
graph_edge_t *tmp_edge;
graph_edge_t *last_edge;
char *token;
boolean_t error = false;
current_vertex = (graph_vertex_t *)malloc(sizeof(graph_vertex_t));
int tmp_number_edges = 1;
/*Temporary character string used to read line in file. */
char *tmp;
/*Allocating memory for string. Again I'm assuming 64 charcters is*/
/*all I need. */
tmp = malloc(sizeof(char) * 64);
while (fgets(tmp,
63,
fp) != NULL
&&
tmp_number_edges > 0)
{
tmp[strcspn(tmp, "\n")] = 0;
/* Check if the line contains a vertex number. */
if (is_number(tmp))
{
/* Set the line to the vertex number. */
tmp_number_edges = atoi(tmp);
}
else
{
/* check if line has the right format. */
token = strtok(tmp, " \t");
if (is_number(token))
{
/* Set the identifier of the vertex. */
current_vertex->identifier = atoi(token);
current_vertex->next_vertex_p = last_vertex;
}
else
{
error = true;
}
token = strtok(NULL, " \t");
if (is_number(token))
{
/* Make new edge. */
tmp_edge = (graph_edge_t *)malloc(sizeof(graph_edge_t));
tmp_edge->adjac_vertex_p = (graph_vertex_t *)malloc(sizeof(graph_vertex_t));
tmp_edge->adjac_vertex_p->identifier = atoi(token);
tmp_edge->next_edge_p = last_edge;
last_edge = tmp_edge;
printf(" %d", tmp_edge->adjac_vertex_p->identifier);
}
else
{
error = true;
}
tmp_number_edges--;
}
}
current_vertex->edge_list_p = tmp_edge;
if(error)
{
current_vertex = NULL;
}
return(current_vertex);
}这个函数是在一个for循环中调用的,这个循环是对顶点数的循环。然后打印一些信息:
printf("connecting to: ");
current_vertex = read_vertex(fp,
last_vertex);
printf(" found vertex ID: %d \n", current_vertex->identifier);因此,我希望得到一个类似于以下内容的输出:
连接到:3 4 5找到顶点ID: 1
连接到:3 4 5找到顶点ID: 2
连接到:12找到顶点ID: 3连接到:1 2 5找到顶点ID: 4
连接到:12 4找到的顶点ID: 5
但实际上看起来是这样的:
连接到:3 4 5找到顶点ID: 1
连接到:3个已找到的顶点ID: 2个连接到:5个已找到的顶点ID: 2个已找到的顶点ID: 3个已找到的顶点ID: 3个已找到的顶点ID:4个
连接到:1个找到的顶点ID: 5
我们可以看到,对于ID 1和4,输出是正确的,但对于其余的输出,则不是。是什么导致了这种行为?我怎么才能解决这个问题?
编辑:
以下是graph_vertex_t和graph_edge_t的定义。
* Structure used to hold a graph vertex information. */
typedef struct graph_vertex
{
int identifier;
struct graph_vertex *next_vertex_p;
struct graph_edge *edge_list_p;
boolean_t visited;
} graph_vertex_t;
/* Structure used to hold a graph edge information. */
typedef struct graph_edge
{
struct graph_vertex *adjac_vertex_p;
struct graph_edge *next_edge_p;
} graph_edge_t;发布于 2020-08-07 12:38:12
从你的话
i首先需要理解sscanf
帮助你阅读这里的一些建议,从你的结构中的任何记忆中选出。
不检查数字的第一项建议是否在分隔线上:
#include <stdio.h>
int main()
{
int nVertices, verticesRank;
if ((scanf("%d", &nVertices) != 1) ||
(nVertices < 0)) {
fputs("wrong number of vertices\n", stderr);
return -1;
}
for (verticesRank = 0; verticesRank < nVertices; verticesRank += 1) {
int nGroups, groupRank, vertex;
if ((scanf("%d", &nGroups) != 1) ||
(nGroups < 0)) {
fprintf(stderr, "wrong number of groups in vertices #%d\n", verticesRank);
return -1;
}
for (groupRank = 0; groupRank < nGroups; groupRank += 1) {
int a, b;
if ((scanf("%d%d", &a, &b) != 2) ||
(a < 1) || (b < 1)) {
fprintf(stderr, "wrong vertex IDs group #%d vertices #%d\n",
groupRank, verticesRank);
return -1;
}
if (groupRank == 0) {
vertex = a;
printf("vertex %d connecting", a);
}
else if (a != vertex) {
fprintf(stderr, "wrong vertex ID group #%d vertices #%d, %d rather than %d\n",
groupRank, verticesRank, a, vertex);
return -1;
}
printf(" %d", b);
}
putchar('\n');
}
return 0;
}汇编和执行:
pi@raspberrypi:/tmp $ gcc -Wall c.c
pi@raspberrypi:/tmp $ cat > v
5
3
1 3
1 4
1 5
3
2 3
2 4
2 5
2
3 1
3 2
3
4 1
4 2
4 5
3
5 1
5 2
5 4
pi@raspberrypi:/tmp $ ./a.out <v
vertex 1 connecting 3 4 5
vertex 2 connecting 3 4 5
vertex 3 connecting 1 2
vertex 4 connecting 1 2 5
vertex 5 connecting 1 2 4
pi@raspberrypi:/tmp $ 第二个版本检查每行值的正确数目:
#include <stdio.h>
int main()
{
char line[64];
int nVertices, verticesRank;
int dummy;
if ((fgets(line, sizeof(line), stdin) == NULL) ||
(sscanf(line, "%d%d", &nVertices, &dummy) != 1) ||
(nVertices < 0)) {
fputs("wrong number of vertices\n", stderr);
return -1;
}
for (verticesRank = 0; verticesRank < nVertices; verticesRank += 1) {
int nGroups, groupRank, vertex;
if ((fgets(line, sizeof(line), stdin) == NULL) ||
(sscanf(line, "%d%d", &nGroups, &dummy) != 1) ||
(nGroups < 0)) {
fprintf(stderr, "wrong number of groups in vertices #%d\n", verticesRank);
return -1;
}
for (groupRank = 0; groupRank < nGroups; groupRank += 1) {
int a, b;
if ((fgets(line, sizeof(line), stdin) == NULL) ||
(sscanf(line, "%d%d%d", &a, &b, &dummy) != 2) ||
(a < 1) || (b < 1)) {
fprintf(stderr, "wrong vertex IDs group #%d vertices #%d\n",
groupRank, verticesRank);
return -1;
}
if (groupRank == 0) {
vertex = a;
printf("vertex %d connecting", a);
}
else if (a != vertex) {
fprintf(stderr, "wrong vertex ID group #%d vertices #%d, %d rather than %d\n",
groupRank, verticesRank, a, vertex);
return -1;
}
printf(" %d", b);
}
putchar('\n');
}
return 0;
}汇编和执行:
pi@raspberrypi:/tmp $ gcc -Wall cc.c
pi@raspberrypi:/tmp $ ./a.out <v
vertex 1 connecting 3 4 5
vertex 2 connecting 3 4 5
vertex 3 connecting 1 2
vertex 4 connecting 1 2 5
vertex 5 connecting 1 2 4
pi@raspberrypi:/tmp $ 注意,我不检查是否有数字以外的其他内容,因此第一行被认为是正确的,例如,如果您需要检查:
#include <stdio.h>
int main()
{
char line[64];
int nVertices, verticesRank;
char dummy;
if ((fgets(line, sizeof(line), stdin) == NULL) ||
(sscanf(line, "%d%c", &nVertices, &dummy) != 2) ||
(nVertices < 0) ||
(dummy != '\n')) {
fputs("wrong number of vertices\n", stderr);
return -1;
}
for (verticesRank = 0; verticesRank < nVertices; verticesRank += 1) {
int nGroups, groupRank, vertex;
if ((fgets(line, sizeof(line), stdin) == NULL) ||
(sscanf(line, "%d%c", &nGroups, &dummy) != 2) ||
(nGroups < 0) ||
(dummy != '\n')) {
fprintf(stderr, "wrong number of groups in vertices #%d\n", verticesRank);
return -1;
}
for (groupRank = 0; groupRank < nGroups; groupRank += 1) {
int a, b;
if ((fgets(line, sizeof(line), stdin) == NULL) ||
(sscanf(line, "%d%d%c", &a, &b, &dummy) != 3) ||
(a < 1) || (b < 1) ||
(dummy != '\n')) {
fprintf(stderr, "wrong vertex IDs group #%d vertices #%d\n",
groupRank, verticesRank);
return -1;
}
if (groupRank == 0) {
vertex = a;
printf("vertex %d connecting", a);
}
else if (a != vertex) {
fprintf(stderr, "wrong vertex ID group #%d vertices #%d, %d rather than %d\n",
groupRank, verticesRank, a, vertex);
return -1;
}
printf(" %d", b);
}
putchar('\n');
}
return 0;
}汇编和执行:
pi@raspberrypi:/tmp $ gcc -Wall cc.c
pi@raspberrypi:/tmp $ ./a.out <v
vertex 1 connecting 3 4 5
vertex 2 connecting 3 4 5
vertex 3 connecting 1 2
vertex 4 connecting 1 2 5
vertex 5 connecting 1 2 4
pi@raspberrypi:/tmp $ 注意,在这种情况下,即使在最后一个期望的数字被认为是一个错误之后,也有一个额外的空格(在换行符之外),最后一行也必须用换行符来完成。
这并不是说在理论结束之后有什么东西,你可以用几种方式去做。
在您的示例中,顶点ID是每个配对中的第一个数字,是连续数字1、2.在我之前的建议中,我不检查,即使检查vertex == verticesRank+1也很容易。如果这是一条规则,那么在只有第二个数字就足够的情况下,为什么要给出这对值呢?
https://stackoverflow.com/questions/63299960
复制相似问题