2017-01-19 12 views
2

構造体をC言語で配列に追加する際に問題があります。私はそれが私の指針を正しく使用していないかもしれないという事実に由来していると思う。C言語の配列に構造体を追加する

は、私は次の構文を使用して、いくつかの構造体を持っている:

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

と私の主な機能には、私が通過してとに私の構造体の変数を設定した後、配列に構造体を追加するforループを持つようにしたい

何か。これまでの完全なコードです:

#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ファイルで使用されています。そのファイルには、行ごとに1つの "char"で区切られた1つの "account"が含まれています。例:

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

問題私の現在のコードでは、配列の中に構造体を入力するように見えるんですが、それは間違ってそれをしません。ここで私は私のコードのループのための第二の印刷文でそれを実行したときに私のコードは私を出してくれるものです:

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

これがこのように動作している理由のため、すべてのすべてのヘルプははるかに高く評価されるだろう。

split_strで
+0

zomgまず、 'strsep()'を使用します。次に、ヒープに構造体を割り当てます.3番目に、文字列( 'strdup()')をコピーする必要があります。 – 0andriy

+0

[** 'strtok' **](http://en.cppreference.com/w/c/string/byte/strtok)が実際には*何か*を読んで、それが'main()' – WhozCraig

答えて

0

問題は、メインにlineのインスタンスが1つしかないため、すべての配列ポインタがその1行を指していることと、最後にfgetsの後に何が含まれているかを指しています。
sscanfを使用して整数とdoubleを解析することができます。 %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); 
    } 
} 
2

()は へのポインタ(位置)を割り当てる関数は任意で split_strのSTRポインタが割り当て解除されているので(左およびおそらくは再利用された 後にぶら下がっているアカウントにローカルストリング後でコード内の他の点は )。

split_strで収集した情報は、関数呼び出しを生き残ることを確認して、あなたが関数内でfnameは(またはLNAMEまたはピンまたは任意の 他のポインタ)にメモリを割り当てる を必要とし、その後、いくつかのmemcpy を使用しますか、 strが を指している情報を、aが指す構造体にコピーする他のメソッド。

+1

いくつかのコードを追加して、どこでエラーが発生しているのか、どのような解決方法で問題を解決できるかを確認してください。 –

関連する問題