Все объекты имеют одинаковое имя - PullRequest
1 голос
/ 08 июля 2011

Я делаю свой последний проект для моего курса алгоритмов на C. Для проекта мы должны взять входной текстовый файл, который содержит строки вроде:

P|A|0

или

E|0|1|2

Первый указывает на вершину, которая будет добавлена ​​к графу, который мы используем в программе, второй токен - это имя вершины, а последний токен - ее индекс в массиве vertices [] структуры графа.

У меня есть цикл while, проходящий через эту программу построчно, он принимает первый токен, чтобы решить, сделать ли вершину или ребро, и затем продолжает действовать соответствующим образом.

Когда я заканчиваю обход файла, я вызываю свою функцию show_vertices, которая является просто циклом for, который печатает каждое имя (g-> vertices [i] .name) последовательно.

Проблема в том, что там, где имя должно идти в выводе (% s), я продолжаю получать последний «токен1», который я собрал. В случае конкретного входного файла, который я использую, он является узлом источника последнего ребра в списке ... что странно, потому что есть два других значения, переданных через функцию strtok () впоследствии. Строка в файле выглядит так:

E|6|7|1

, который создает ребро из индексов 6-7 с весом 1. Ребро подходит хорошо. Но когда я звоню любому printf с% s, он появляется "6". Независимо от того.

Это обход файла.

fgets(currLn, sizeof(currLn), infile);
maxv = atoi(currLn);
if(maxv = 0)
{
    //file not formatted correctly, print error message
    return;
}

t_graph *g = new_graph(maxv, TRUE);

while((fgets(currLn, sizeof(currLn), infile)) != NULL)
{
    token1 = strtok(currLn, "|");
    key = token1[0];

    if(key == 'P' || key == 'p')
    {
        token1 = strtok(NULL, "|");
        if(!add_vertex(g, token1))
        {
            //file integration fail, throw error!
            return;
        }
        //***If I print the name here, it works fine and gives me the right name!****
        continue;
    }
    if(key == 'E' || key == 'e')
    {
        token1 = strtok(NULL, "|");
        token2 = strtok(NULL, "|");
        token3 = strtok(NULL, "|");
        src = atoi(token1);
        dst = atoi(token2);
        w = atoi(token3);

        if(!add_edge(g, src, dst, w))
        {
            //file integration fail, throw error
            return;
        }
        continue;
    }
    else
    {
        //epic error message because user doesn't know what they're doing.
        return;
    }
}

Если я запускаю show_vertices здесь, я получаю:

0. 6  
1. 6  
2. 6  
etc...

1 Ответ

2 голосов
/ 08 июля 2011

Вы не копируете имя. Таким образом, вы получите указатель (возвращаемый strtok) на один статический массив, в котором вы читаете каждую строку. Поскольку имя всегда находится со смещением 2, указатель всегда будет currLn+2. Когда вы пройдете и напечатаете, это будет фамилия, которую вы прочитали.

Вам необходимо strdup(token1), прежде чем передать его (или в) add_vertex.

Нет, недостаточно информации, чтобы убедиться, что это ответ. Но я держу пари, вот и все.

...