2017-02-18 20 views
1

В моем коде я читаю имена и телефонные номера файла и имена, соответствующие номерам телефонов. Проблема, которую я получаю в моем коде, - это после цикла for в моей функции загрузки.Случайное изменение значений массива структур

Эта проблема случайным образом меняет все значения имени моей структуры на последнее присвоенное имя. Также я не понимаю, как конвертировать из разделительного токена в float из строки.

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


struct _data { 
    char *name; 
    long number; 
}; 

int SCAN(FILE *(*stream)){ 
    int count; 
    char dataString[50]; 
    int check = 1; 
    count = 0; 

    while(check){ 
      fscanf(*stream, "%s\n", dataString); 
      fscanf(*stream, "%s\n", dataString); 
      if (feof(*stream)){ 
       check = 0; 
      } 
      count++; 
    }  
    return count; 
} 

struct _data *LOAD(FILE *stream, int size){ 
    int x; 
    char *tempLine; 
    size_t length = 0; 
    const char delim[2] = " "; 
    char *token; 

    rewind(stream); 
    struct _data *array = malloc(sizeof(struct _data) * size); 
    printf("this is the size: %d\n\n", size); 
    for(x = 0; x < size; x++){ 
      getline(&tempLine, &length, stream); 
      token = strtok(tempLine, delim); 
      //printf("this is inside the for loop of load: %s\n", token); 
      array[x].name = token; 
      token = strtok(tempLine, delim); 
      //printf("this is the token: %s\n", token); 
      array[x].number = atol(token); 
      printf("this is name %s, and phone number %ld\n", array[x].name, array[x].number); 
    } 
    printf("i am now outside the initial for loop in load\n\n"); 
    for(x = 0; x < size; x++){ 
       printf("this is name %s, and phone number %ld\n", array[x].name, array[x].number); 
      } 
    return array; 

} 

void SEARCH(struct _data *BlackBox, char *name, int size){ 
    int x; 
    int check = 0; 
    for(x = 0; x < size; x++){ 
      printf("BlackBox Name: %s, check name: %s\n", BlackBox[x].name, name); 
      //printf("this is the check: %d\n", strcmp(BlackBox[x].name, name)); 
      if (0 == strcmp(BlackBox[x].name, name)){ 
       printf("*******************************************\n"); 
       printf("The name was found at the %d entry.\n", x); 
       printf("*******************************************\n"); 
       check = 1; 
      } 
    } 
    if (check == 0){ 
      printf("*******************************************\n"); 
      printf("The name was NOT found.\n"); 
      printf("*******************************************\n"); 
    } 
} 

void FREE(struct _data *BlackBox, int size){ 
    free(BlackBox); 
} 

int main(int argv, char **argc){ 
    FILE *fp; 
    int size; 
    int x; 
    struct _data *BlackBox; 
    if(argv < 2){ 
      printf("*******************************************\n"); 
      printf("* You must include a name to search for. *\n"); 
      printf("*******************************************\n"); 
    }else{ 
      fp = fopen("hw5.data", "r"); 
      size = SCAN(&fp); 
      BlackBox = LOAD(fp, size); 
     /* for(x = 0; x < size; x++){ 
       printf("BlackBox Name: %s, check name: %s\n", BlackBox[x].name, argc[1]); 
      }*/   
      SEARCH(BlackBox, argc[1], size); 
      FREE(BlackBox, size); 
    } 
    return 0; 
} 

Вот мой вход

ron 7774013 
jon 7774014 
tom 7774015 
won 7774016 
bonny 7774017 

Вот мой выход

ron 0 
jon 0 
tom 0 
won 0 
bonny 0 
i am now outside the initial for loop in load 
bonny 0 
bonny 0 
bonny 0 
bonny 0 
bonny 0 
+0

'array [x] .name = token;' только копирует указатель места в 'tempLine', вероятно, вы хотите получить копию строки. – chux

ответ

1

Вы многократно использовать пространство, выделенное на getline() - так что вы видите только последние значения. Вам необходимо установить tempLine в NULL и length в 0 после цикла. Вы также должны проверить возвращаемое значение от getline(), чтобы убедиться, что вы действительно получили данные для чтения.

Ваш второй звонок strtok() должен использовать указатель NULL. Отменяя tempLine, вы преобразуете имя в число.

 getline(&tempLine, &length, stream); 
     token = strtok(tempLine, delim); 
     //printf("this is inside the for loop of load: %s\n", token); 
     array[x].name = token; 
     token = strtok(tempLine, delim); 
        ^^^ should be NULL! 

Вы должны были заметить эту проблему, когда печатаете токен.

Этот код может работать по желанию - он не был скомпилирован.

struct _data *LOAD(FILE *stream, int size) 
{ 
    char *tempLine = NULL; 
    size_t length = 0; 
    const char delim[] = " "; 
    char *token; 
    int x; 

    rewind(stream); 
    struct _data *array = malloc(sizeof(struct _data) * size); 
    printf("this is the size: %d\n\n", size); 
    for (x = 0; x < size; x++) 
    { 
     if (getline(&tempLine, &length, stream) == -1) 
     { 
      free(tempLine); 
      break; 
     } 
     token = strtok(tempLine, delim); 
     // printf("this is inside the for loop of load: [%s]\n", token); 
     array[x].name = token; 
     token = strtok(NULL, delim); 
     // printf("this is the token: [%s]\n", token); 
     array[x].number = atol(token); 
     printf("%d: this is name %s, and phone number %ld\n", x, array[x].name, array[x].number); 
     length = 0; 
     tempLine = NULL; 
    } 
    printf("i am now outside the initial for loop in load\n\n"); 
    for (int i = 0; i < x; i++) 
    { 
     printf("%d: this is name %s, and phone number %ld\n", i, array[i].name, array[i].number); 
    } 
    return array; 
} 

Также обратите внимание, что вы должны вообще избегать создания имен, которые начинаются с символа подчеркивания (например, как struct _data). Многие такие имена зарезервированы для использования реализацией; проще всего создавать имена, начинающиеся с подчеркивания вообще.

+0

Да !!! это сработало, спасибо! Но да, это я использую предопределенные функции от моего профессора, поэтому именно поэтому у меня были имена таким образом (так он определил их в домашнем задании). –

+0

Вы не можете помочь профессорам, у которых плохие привычки кодирования. Обратите внимание на проблему, спросите об этом, если вы храбры и помните о своей работе. –

+0

, поэтому проблема заключалась в том, что у меня было имя на каждом индексе, установленном на указатель. Из-за этого он перенаправлялся на адрес указателя, который, в свою очередь, имел последнее значение, я прав в этом предположении? –