在我的代码中,我正在读取文件的名称和电话号码,以及与电话号码对应的名称。我在代码中遇到的问题是在加载函数中的for循环之后。
此问题将随机将结构名称的所有值更改为最后分配的名称。另外,我不完全理解如何从拆分标记转换为字符串中的浮点数。

#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

最佳答案

您一直在重复使用getline()分配的空间,因此只能看到最后的值。循环后需要将tempLine设置为空,并将length设置为0。您还应该检查getline()中的返回值,以确保您确实有要读取的数据。
strtok()的第二次调用应该使用空指针。通过重新指定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)。许多这样的名称是为实现保留的;避免创建以下划线开头的名称是最简单的。

09-08 04:48