随机改变结构数组的值

时间:2017-02-18 00:51:27

标签: c struct dynamic-memory-allocation

在我的代码中,我正在阅读文件的名称和电话号码以及与电话号码对应的名称。我在我的代码中遇到的问题是在我的加载函数中的for循环之后。

此问题会将我的struct name的所有值随机更改为最后指定的名称。另外,我完全不了解如何从分割标记转换为从字符串浮动。

#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

1 个答案:

答案 0 :(得分: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)。许多此类名称保留供实施使用;最简单的方法是避免创建以下划线开头的名称。