链表中的C指针

时间:2012-10-14 11:11:16

标签: c pointers

做一个家庭作业,我遇到了问题,我相信,指针。

作业包括以下内容:

我有一个txt文件,其中每一行都是名称和密码。

thisismyname:thisismypassword

我必须读取这些数据,将其处理为结构链表,运行所有列表并将密码发送给暴力算法。在找到传递之后,该算法应该在结构上写入传递。最后,我应该运行列表并将数据写入txt文件

我的问题是当我找到密码时。它不会将其值存储在结构中。最后我可以读取数据,我可以看到蛮力正在运行,但最后,我只是设法写出名称并传递给文件。未加密的传递被写为NULL,所以我认为是一个指针问题。

这是代码(删除了我认为无关紧要的所有内容):

typedef struct p {
    char *name;
    char *pass;
    char *pass_desenc;
    struct p *next_person;
} person;

typedef struct n {
    int a;
    int b;
} numbers;

int readFile(person **people) {
    FILE * fp;
    char line[100];

    if ((fp = fopen(STUDENTS_FILE, "r")) != NULL) {
        while (fgets(line, sizeof (line), fp) != NULL) {
            person *p;
            char email[27] = "";
            char password[14] = "";
            char *change = strchr(line, '\n');
            if (change != NULL)
                *change = '\0';

            /* Gets email*/
            strncpy(email, line, 26);
            email[27] = '\0';

            /* Gets pass*/
            strncpy(password, line + 27, 14);
            password[14] = '\0';

            p = (person*) malloc(sizeof (person));
            if (p == NULL) {
                return -1;
            }

            p->name = (char*) malloc(strlen(email));
            if (p->name == NULL) {
                return -1;
            }
            sprintf(p->name, "%s", email);
            p->name[strlen(email)] = '\0';

            p->pass = (char*) malloc(strlen(password));
            if (p->pass == NULL) {
                return -1;
            }
            sprintf(p->pass, "%s", password);
            p->pass[strlen(password)] = '\0';

            p->next_person = (*people);
            (*people) = p;

            countPeople++;
        }
        fclose(fp);

        return 0;
    }
    return -1;
}

void fmaps(int id, numbers pass_range, person *people) {
        /*This function will run all my list and try to uncrypt pass by pass.
            On the brute-force pass in unencrypted and when it return to this function, I can print the data.
        */
        while (people != NULL && j > 0) {
            for (i = 1; i <= PASS_SIZE && notFound == 1; i++) {
                notFound = bruteForce(i, people, &total_pass);
            }
            notFound = 1;
            count = count + total_pass;

            printf("#####Email: %s Pass: %s PassDesenq: %s \n", people->name, people->pass, people->pass_desenc);

            people = people->next_person;
            j--;
        }
}

void fcontrol(int n, person *people) {
    /*This function should write the data to a file
    I can see that all data is written as expected but people->pass_desenc is writing/printing NULL
    */

    if ((fp = fopen(STUDENTS_LOG_FILE, "a+")) != NULL) {
        while (people != NULL) {
            printf("#####1111Email: %s Pass: %s PassDesenq: %s \n", people->name, people->pass, people->pass_desenc);
            fprintf(fp, "%d%d%d%d%d%d:grupo%d:%s:%s\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, 1, people->name, people->pass_desenc);
            people = people->next_person;
        }
    }
    fclose(fp);
}

int main() {

    /*Struct*/
    person *people = NULL;

    if (readFile(&people)) {
        printf("Error reading file!\n");
        return 0;
    }
    /*Function to send data to brute-force*/
    fmaps(i, pass_range, people);
    /*After all data is processed, this function writes the data to a file*/
    fcontrol(NR_PROC, people);

    destroyList(&people);

    return 0;
}

int bruteForce(int size, person *people, int *total_pass) {
    int i;
    char *pass_enc;
    int *entry = (int*) malloc(sizeof (size));
    char pass[50];
    char temp;
    pass[0] = '\0';


    for (i = 0; i < size; i++) {
        entry[i] = 0;
    }
    do {
        for (i = 0; i < size; i++) {
            temp = (char) (letters[entry[i]]);
            append(pass, temp);
        }

        (*total_pass)++;

        /*Compare pass with test*/
        pass_enc = crypt(pass, salt);


        if (strcmp(pass_enc, people->pass) == 0) {

            people->pass_desenc = (char*) malloc(strlen(pass));
            if (people->pass_desenc == NULL) {
                return -1;
            }

            sprintf(people->pass_desenc, "%s", pass);
            people->pass_desenc[strlen(pass)] = '\0';
            return 0;
        }

        pass[0] = '\0';
        for (i = 0; i < size && ++entry[i] == nbletters; i++) {
            entry[i] = 0;
        }

    } while (i < size);


    free(entry);


    return 1;
}

void append(char *s, char c) {
    int len = strlen(s);
    s[len] = c;
    s[len + 1] = '\0';
}

void destroyList(person **people) {
    person *aux;
    printf("\nList is being destroyed.");
    while (*people != NULL) {
        aux = *people;
        *people = (*people)->next_person;
        free(aux);
        printf(".");
    }
    printf("\nList destroyed.\n");
}

我认为fmaps中所做的更改是本地更改,而不是传递给main

感谢任何帮助...

1 个答案:

答案 0 :(得分:1)

这就是 编码文件阅读器/解析器的方式。它避免了str [n] cpy(),并使用memcpy()+偏移+大小进行所有字符串操作。 (显然,两种情况都需要正确)

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

typedef struct p {
    char *name;
    char *pass;
    // char *pass_desenc;
    struct p *next;
} person;

#define STUDENTS_FILE "students.dat"
unsigned countPeople = 0;

int readFile(person **people) {
    FILE * fp;
    char line[100];
    size_t len, pos;

    fp = fopen(STUDENTS_FILE, "r");
    if (!fp)  {
        fprintf(stderr, "Could not open %s:%s\n"
                , STUDENTS_FILE, strerror(errno));
        return -1;
        }

    while ( fgets(line, sizeof line, fp) ) {
        person *p;

        len = strlen(line);

        /* remove trailng '\n', adjusting the length */
        while (len && line[len-1] == '\n') line[--len] = 0;

        /* Ignore empty lines */
        if ( !len ) continue;

        /* Library function to count the number of characters in the first argument
        ** *not* present in the second argument.
        ** This is more or less equivalent to strtok(), but
        ** 1) it doen not modify the string,
        ** 2) it returns a size_t instead of a pointer.
        */
        pos = strcspn(line, ":" );

        /* Ignore lines that don't have a colon */
        if (line[pos] != ':') continue;

        p = malloc(sizeof *p);
        if ( !p ) { fclose(fp); return -2; }
        p->next = NULL;

        p->name = malloc(1+pos);
        if ( !p->name ) { fclose(fp); return -3; } /* this could leak p ... */
        memcpy(p->name, line, pos-1);
        p->name[pos] = 0;

        p->pass = malloc(len-pos);
        if ( !p->pass ) {fclose(fp); return -4; } /* this could leak p and p->name */
        memcpy(p->pass, line+pos+1, len-pos);

        /* Instead of pushing (which would reverse the order of the LL)
        ** , we append at the tail of the LL, keeping the original order.
        */
        *people = p;
        people = &p->next ;

        countPeople++;
    }

    fclose(fp);
    return 0;
}