在C中向数组添加结构

时间:2017-01-19 20:09:08

标签: c arrays pointers struct

我在使用C语言向数组添加结构时遇到问题。我认为这是因为我可能没有正确使用指针。

我有一些结构,语法如下:

struct account
{
     int num;
     char* fname;
     char* lname;
     char* pin;
     double bal;
};

并且在我的main函数中我希望有一个for循环,它在经过并将我的struct的变量设置为某个东西之后为数组添加了一个struct。到目前为止,这是我的完整代码:

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

struct account
{
     int num;
     char* fname;
     char* lname;
     char* pin;
     double bal;
};

void split_str (struct account *a,char *line)
{
     int i = 0; //incrementer to tell what we are looking at: num, fname, lname, pin, or bal

    int acc_num; //temp vals to store acc_num casting and balance casting
    double bal;

    char * str;

    str = strtok(line, " ");

    while (str!= NULL){
        switch(i){
            case 0:
                acc_num = atoi(str);
                a->num = acc_num;

                acc_num = 0;
                break;

            case 1:
                a->fname = str;
                break;

            case 2:
                a->lname = str;
                break;

            case 3:
                a->pin = str;
                break;

            case 4:
                bal = atof(str);
                a->bal = bal;

                bal = 0;
                break;
        }
        str = strtok (NULL, " ");
        i++; //increment because we want to look through all 5 possibilities of vars
    }
}

int main()
{
     FILE *fh = fopen("account_info.txt", "r");
     struct account accts[100];

     if (fh != NULL)
     {
          char line[256];

          for (int i=0; fgets(line, sizeof line, fh) != NULL; i++)
          {
               split_str(&accts[i], line);
          }
     }
     fclose(fh);

     for (int i=0; i<3; i++)
     {
          printf("%s %s index: %i\n", accts[i].fname, accts[i].lname, i);
     }
}

此代码与account_info.txt文件一起使用。所有该文件包含的每行一个“帐户”用空格“”字符分隔。例如:

123456 Jane Doe 1234 250.50
123457 John Smith 2222 12.34
123458 Sally Jones 9999 321.79

问题与我当前的代码一样,它似乎确实在数组中输入了一个结构,但是它做错了。当我在我的代码的第二个for循环中使用print语句运行它时,我的代码向我吐出了这些内容:

Sally Jones index: 0
Sally  index: 1
Sally Jones index: 2

对于为什么采用这种方式行事的任何帮助都将非常感激。

2 个答案:

答案 0 :(得分:2)

在split_str()中,您要指定指针(位置) 帐户中悬挂的本地字符串 该函数已被保留(因为str指针在 split_str被解除分配并可能在任何地方重用 稍后代码中的其他点...)。

确保收集到的信息 你需要split_str幸存下来的函数调用 分配内存到fname(或lname或pin或任何 在函数中使用其他指针),然后使用一些memcpy 或其他方法来复制str指向的信息 进入a。指向的结构。

答案 1 :(得分:0)

问题是main中只有一个line实例,因此所有数组指针都指向那一行以及它在最后fgets之后包含的内容。
sscanf可用于解析整数和双精度。使用%n说明符,可以捕获名称和引脚的起始和停止索引。 %*s说明符将读取并丢弃字符串,因为它们的长度尚不清楚。一旦知道了起始和终止索引,就可以分配内存并使用memcpy复制字符串。

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

struct account
{
     int num;
     char* fname;
     char* lname;
     char* pin;
     double bal;
};

int split_str (struct account *a,char *line)
{
    int startfn = 0;
    int stopfn = 0;
    int startln = 0;
    int stopln = 0;
    int startpin = 0;
    int stoppin = 0;

    if ( ( 2 == sscanf ( line, "%d %n%*s%n %n%*s%n %n%*s%n %lf"
    , &(a->num)
    , &startfn
    , &stopfn
    , &startln
    , &stopln
    , &startpin
    , &stoppin
    , &(a->bal)))) {

        if ( ( a->fname = malloc ( ( stopfn - startfn) + 1)) == NULL) {
            fprintf ( stderr, "problem malloc\n");
            exit ( 1);
        }
        memcpy ( a->fname, &line[startfn], stopfn - startfn);
        a->fname[stopfn - startfn] = '\0';
        if ( ( a->lname = malloc ( ( stopln - startln) + 1)) == NULL) {
            fprintf ( stderr, "problem malloc\n");
            exit ( 1);
        }
        memcpy ( a->lname, &line[startln], stopln - startln);
        a->lname[stopln - startln] = '\0';
        if ( ( a->pin = malloc ( ( stoppin - startpin) + 1)) == NULL) {
            fprintf ( stderr, "problem malloc\n");
            exit ( 1);
        }
        memcpy ( a->pin, &line[startpin], stoppin - startpin);
        a->pin[stoppin - startpin] = '\0';
        return 1;
    }
    return 0;
}

int main()
{
     FILE *fh = fopen("account_info.txt", "r");
     struct account accts[100];
     int loaded = 0;

     if (fh != NULL)
     {
          char line[256];

          for (int i=0; fgets(line, sizeof line, fh) != NULL; i++)
          {
               if ( split_str(&accts[i], line)) {
                   loaded++;
               }
          }
     }
     fclose(fh);

     for (int i=0; i<loaded; i++)
     {
          printf("%s %s index: %i\n", accts[i].fname, accts[i].lname, i);
     }
     for (int i=0; i<loaded; i++)//free allocated memory
     {
        free ( accts[i].fname);
        free ( accts[i].lname);
        free ( accts[i].pin);
    }
}