• ベストアンサー

C言語 構造体(2)

ご質問です。 構造体で、あらかじめメンバ数を固定したものではなく、 テキストファイルを読み込んだときにメンバ数を変えて読み込みたいのです。 (カンマできりたい) aaa.txt ------------------------ あああ,いいい ------------------------ となっているときは、 tmp.nm[0]=あああ tmp.nm[1]=いいい となり、 kamoku.nm[0] kamoku.nm[1] をprintf。 aaa.txt --------------------------- あああ,いいい,ううう,えええ --------------------------- の場合は tmp.nm[0]=あああ tmp.nm[1]=いいい tmp.nm[2]=ううう tmp.nm[3]=えええ kamoku.nm[0] kamoku.nm[1] kamoku.nm[2] kamoku.nm[3] をprintf。 下記は動きません。。 よろしくお願いいたします。 #include <stdio.h> struct kamokumei { char nm[10]; }kamoku; int main(void) { int i,P,t; FILE *fp; struct kamokumei kamoku[20]; char buf[1024]; fp = fopen("aaa.txt", "r"); P=3; t=0; while( fgets(buf, sizeof(buf), fp) ){ struct kamokumei tmp; sscanf(buf, "%s", tmp.nm[t]); nm[t++] = tmp; } for(i = 0; i < P; i++) { printf("%s\n", kamoku.nm[i]); } return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.1

FILE *fp; char buf[1024]; while( fgets(buf, sizeof(buf), fp) ) これだと 1行が1024文字以上だと当然うまく読み込めません。 まずその部分から改善する必要があります。 #include <stdio.h> #include <string.h> #include <malloc.h> #define MAX_BUF 2 int main() { FILE *fp; int len; char buf[MAX_BUF]; int buflen; fp = fopen("aaa.csv", "r"); char *pBuf2 = NULL; while( fgets(buf, MAX_BUF , fp) ){ int buflen = strlen(buf); if ( buf[buflen - 1] == '\n'){ buf[buflen - 1] = '\0'; pBuf2 = (char*)realloc( pBuf2 , buflen ); printf("%s\n",pBuf2); if (pBuf2) free(pBuf2); pBuf2 = NULL; }else{ if ( pBuf2 == NULL ){ pBuf2 = (char*)malloc( buflen + 1 ); strcpy( pBuf2 , buf ); }else{ pBuf2 = (char*)realloc( pBuf2 , buflen + 1 ); strcat( pBuf2 , buf ); } } } if (pBuf2) free(pBuf2); }

その他の回答 (5)

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.6

訂正 int i,j; for( i = 1 ; i <= mycsv.cnt ; i++ ){ printf( "(mycsv.line + i)->cnt=%d\n" , (mycsv.line + i - 1)->cnt ); for( j = 1 ; j <= (mycsv.line + i - 1)->cnt ; j++ ){ printf( "%d行目%d列目は「%s」\n" ,i,j, ReadCsv( &mycsv , i-1 , j-1 ) ); } } ちなみにこのソース、最後が改行で終わっていなければ 最後の行が読まれませんでした。 printf( "2行目3列目は「%s」" , ReadCsv( &mycsv , 2 - 1 , 3 - 1 ) ); の上に if (pBuf2) AddCsv( &mycsv , pBuf2 ); を追加すれば解消します。

cluewm
質問者

お礼

沢山の回答ありがとうございました。 大変勉強になりました。 (が、結局可変長のところはうまくいかず締め切りがきてしまいました、、) もう少し勉強していきたいと思います。 今後ともよろしくお願いいたします。

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.5

>aaa.txtを読み込んだ時の >最大行の数、最大列の数はどの変数にあたるのでしょうか? 最大行の数:mycsv->cnt 1行目の最大列の数:mycsv->line->cnt 2行目の最大列の数:(mycsv->line + 1)->cnt int i,j; for( i = 1 ; i <= mycsv->line->cnt ; i++ ){ for( j = 1 ; j <= (mycsv->line + i)->cnt ; j++ ){ printf( "%d行目%d列目は「%s」" ,i,j, ReadCsv( &mycsv , i-1 , j-1 ) ); } }

cluewm
質問者

補足

早速回答を頂きありがとうございます。 すみません、再々度質問なのですが、、 -> か ->* の左には構造体のポインタが必要 とerrorがでます。 ポインタについて本を読みながらやっているものの、 解決できません、、 よろしくお願いいたします。 http://oshiete1.goo.ne.jp/kotaeru.php3?q=1217707 でも受け付けています。

  • const
  • ベストアンサー率66% (12/18)
回答No.4

最終的に何がしたいのかわからないのですが、元のソースをベースに1行を分割するものを書いてみます。 複数の行ならばkamokuを二次元配列にする必要があり、最大の列・行数が不定ならばsha-girlさんのように書く必要があります。 #include <stdio.h> #include <string.h> struct kamokumei { char name[32]; }; static char *split(char *buf, char delimiter) { char *next = strchr(buf, delimiter); if (next == NULL) return buf + strlen(buf); *next = '\0'; return next + 1; } static int split_csvline(char *buf, struct kamokumei *dest, int max) { char *next, *item; int i; for(i = 0, item = next = buf; *next != '\0' && i < max; i++, item = next) { next = split(item, ','); strcpy(dest[i].name, item); } return i; } int main(void) { int i, count, length; FILE *fp; struct kamokumei kamoku[20]; char buf[1024]; fp = fopen("aaa.txt", "r"); if (fgets(buf, sizeof buf, fp)) { buf[sizeof buf - 1] = '\0'; length = strlen(buf); if (buf[length - 1] == '\n') buf[length - 1] = '\0'; count = split_csvline(buf, kamoku, sizeof kamoku / sizeof kamoku[0]); for(i = 0; i < count; i++) printf("%s\n", kamoku[i].name); } return 0; } ちなみにテキストファイルを処理して出力するだけならばperlをお勧めします。 open(FP, "<aaa.txt") or die; while (<FP>) { chomp; @columns = split(/,/); push(@csv, [@columns]); } printf('2行目3列目は「%s」' , $csv[2-1]->[3-1]);

cluewm
質問者

補足

回答を頂いた皆様へ ありがとうございます。 >二次元配列にする必要があり、最大の列・行数が不定ならば・・・ できれば二次元配列にしたいので、sha-girlさんから回答いただいたソースを元にしたいと思います。 printf( "2行目3列目は「%s」" , ReadCsv( &mycsv , 2 - 1 , 3 - 1 ) ); は、理解できたのですが、 その他の動きがまったくわからない状態です、、 aaa.txtを読み込んだ時の 最大行の数、最大列の数はどの変数にあたるのでしょうか? たとえば、 最大行の数=x 最大列の数=y i=1,j=1として、 i=1 to x j=1 to y とし、ループで全部表示させることが目的です。 printf( "%d行目%d列目は「%s」" , i,j,ReadCsv( &mycsv , i - 1 , j - 1 ) );

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.3

とりあえず書いてみました。 aaa.csvから読み込み char* ReadCsv( MYCSV* pCsv , int l , int r ) の関数で読み込みます。 printf( "2行目3番目は「%s」" , ReadCsv( &mycsv , 2 - 1 , 3 - 1 ) ); の部分で2行目3番目にある項目を表示しています。 #include <stdio.h> #include <string.h> #include <malloc.h> typedef struct ___mycsvline{ int cnt; char **str; } MYCSVLINE; typedef struct ___mycsv{ int cnt; MYCSVLINE* line; } MYCSV; #define MAX_BUF 2 char* ReadCsv( MYCSV* pCsv , int l , int r ) { MYCSVLINE* pLine; if ( l >= pCsv->cnt ){ return ""; } pLine = (pCsv->line + l ); if ( r >= pLine->cnt ){ return ""; } return *(pLine->str + r); } int GetStrToken(char* str){ int cnt = 0; while( *str != '\0' && *str != ',' ){ cnt++; str++; } return cnt; } int GetConmaCnt(char* str){ int cnt = 0; while( *str != '\0'){ if ( *str == ',' ) cnt++; str++; } return cnt; } void AddLine( MYCSVLINE* pLine , char* str ){ int i; int NextConma; int ConmaCnt = GetConmaCnt(str); pLine->cnt = ConmaCnt + 1; pLine->str = (char**)malloc( sizeof(char*) * pLine->cnt ); for( i = 0 ; i < pLine->cnt ; i++ ){ NextConma = GetStrToken(str); *(pLine->str + i) = (char*)malloc( NextConma + 1 ); strncpy( *(pLine->str + i) , str , NextConma ); *( *(pLine->str + i) + NextConma ) = '\0'; str += ( NextConma ); if ( *str == ',' ) str++; } } void AddCsv( MYCSV* pCsv , char* str ){ pCsv->cnt++; pCsv->line = (MYCSVLINE*)realloc( pCsv->line , sizeof( MYCSV ) * pCsv->cnt ); AddLine( (pCsv->line + (pCsv->cnt - 1) ) , str ); } void AllFree( MYCSV* pCsv ){ int i,j; MYCSVLINE* pLine; for ( i = 0 ; i < pCsv->cnt ; i++ ){ pLine = (pCsv->line + i); for( j = 0 ; j < pLine->cnt ; j++ ){ free( *(pLine->str + j) ); } free(pLine->str); } free( pCsv->line ); } int main() { FILE *fp; char buf[MAX_BUF]; int buflen; int ttlbuflen = 0; fp = fopen("aaa.csv", "r"); char *pBuf2 = NULL; MYCSV mycsv; mycsv.cnt = 0; mycsv.line = NULL; while( fgets(buf, MAX_BUF , fp) ){ buflen = strlen(buf); ttlbuflen += buflen; if ( buf[buflen - 1] == '\n'){ buf[buflen - 1] = '\0'; if (pBuf2 == NULL){ pBuf2 = (char*)malloc( ttlbuflen + 1 ); strcpy( pBuf2 , buf ); }else{ pBuf2 = (char*)realloc( pBuf2 , ttlbuflen + 1 ); strcat( pBuf2 , buf ); } AddCsv( &mycsv , pBuf2 ); if (pBuf2) free(pBuf2); ttlbuflen = 0; pBuf2 = NULL; }else{ if ( pBuf2 == NULL ){ pBuf2 = (char*)malloc( ttlbuflen + 1 ); strcpy( pBuf2 , buf ); }else{ pBuf2 = (char*)realloc( pBuf2 , ttlbuflen + 1 ); strcat( pBuf2 , buf ); } } } printf( "2行目3列目は「%s」" , ReadCsv( &mycsv , 2 - 1 , 3 - 1 ) ); AllFree( &mycsv ); if (pBuf2) free(pBuf2); }

cluewm
質問者

お礼

回答を頂いた皆様へ ありがとうございます。 >二次元配列にする必要があり、最大の列・行数が不定ならば・・・ できれば二次元配列にしたいので、sha-girlさんから回答いただいたソースを元にしたいと思います。 printf( "2行目3列目は「%s」" , ReadCsv( &mycsv , 2 - 1 , 3 - 1 ) ); は、理解できたのですが、 その他の動きがまったくわからない状態です、、 aaa.txtを読み込んだ時の 最大行の数、最大列の数はどの変数にあたるのでしょうか? たとえば、 最大行の数=x 最大列の数=y i=1,j=1として、 i=1 to x j=1 to y とし、ループで全部表示させることが目的です。 printf( "%d行目%d列目は「%s」" , i,j,ReadCsv( &mycsv , i - 1 , j - 1 ) );

  • sha-girl
  • ベストアンサー率52% (430/816)
回答No.2

#1です。ちょっと下のソースおかしかったので訂正しときます。 int main() { FILE *fp; char buf[MAX_BUF]; int buflen = 0; int ttlbuflen = 0; fp = fopen("aaa.csv", "r"); char *pBuf2 = NULL; char* pp; while( fgets(buf, MAX_BUF , fp) ){ buflen = strlen(buf); ttlbuflen += buflen; if ( buf[buflen - 1] == '\n'){ buf[buflen - 1] = '\0'; if (pBuf2 == NULL){ pBuf2 = (char*)malloc( ttlbuflen + 1 ); strcpy( pBuf2 , buf ); }else{ pBuf2 = (char*)realloc( pBuf2 , ttlbuflen + 1 ); strcat( pBuf2 , buf ); } printf("%s\n",pBuf2); if (pBuf2) free(pBuf2); ttlbuflen = 0; pBuf2 = NULL; }else{ if ( pBuf2 == NULL ){ pBuf2 = (char*)malloc( ttlbuflen + 1 ); strcpy( pBuf2 , buf ); }else{ pBuf2 = (char*)realloc( pBuf2 , ttlbuflen + 1 ); strcat( pBuf2 , buf ); } } } if (pBuf2) free(pBuf2); } ところでC++(stlのvectorやstring)を使うっていうのは無しですよね? Cのみで構造体を可変長にする場合、上記と同じようにreallocやmalloc、callocを 使用します。 可変長文字列かつ可変長リストであるなら typedef struct ___mycsvline{ int cnt; char **str; } MYCSVLINE; typedef struct ___mycsv{ int cnt; MYCSVLINE* line; } MYCSV; CSVは構造体はこんな定義でどうでしょう。

関連するQ&A

  • C言語 構造体

    以前にも構造体について質問させていただきましたが、より自由度の高い処理が必要となりご質問させていただきます。 よろしくお願いいたします。 以前のものは入力する項目数(列),行数(行)が前提にあるものでした。 テキストファイルを読み込んで、 構造体としてデータを読み込みたいのですが、 今回は項目数が不定のものです。 a.txt ------------------------- あああ,いいい,ううう ------------------------- とあれば あああ いいい ううう とカンマ抜きで得たい。(3項目) 次回読み込んだとき、 a.txt ------------------------- abc,def,g,h,i,jk ------------------------- とあれば、 abc def g h i jk とカンマ抜きで得たい。(6項目) 以前のものは下記のような感じです。 FILE *fp; FILE *file; struct seiseki seito[20]; char buf[1024]; fp = fopen("aaa.txt", "r"); i=0; while( fgets(buf, sizeof(buf), fp) ){ struct seiseki tmp; sscanf(buf,"%d %s %s %d %d %d",&tmp.no,tmp.lname,tmp.fname,&tmp.val[0],&tmp.val[1],&tmp.val[2]); seito[i++] = tmp; } for(i = 0; i < 3; i++) { printf("%d / %s %s / %d / %d / %d / %d\n", seito[i].no,seito[i].lname,seito[i].fname, seito[i].val[0], seito[i].val[1], seito[i].val[2], seito[i].val[0] + seito[i].val[1] + seito[i].val[2]); }

  • C言語での構造体

    C言語の構造体で配列を扱うとき、 struct ○○{  char ○○[○] とすれば出来ますが、同じようにして構造体で二次元配列を扱うことは出来ますか? 一度組んでみたのですが、 #include<stdio.h> struct aaa{ int no; char name[128]; char y_name[128]; char n_name[128]; char s_name[128][128]; }; int main(void){ int i; struct aaa iryo[99]; printf("入力前\n"); /* 構造体配列に scanf()でデータを入力 */ for(i = 0; i < 3; i++) { // printf("input...\n"); scanf("%d", &iryo[i].no); scanf("%s", iryo[i].name); scanf("%s", iryo[i].y_name); scanf("%s", iryo[i].n_name); scanf("%s", iryo[i].s_name); } printf("入力後\n"); printf("出力前\n"); /* 入力データの確認 */ for(i = 0; i < 3; i++) { printf("番号:%02d 内容:%s Y分岐:%s N分岐:%s 他分岐:%s\n", iryo[i].no, iryo[i].name, iryo[i].y_name, iryo[i].n_name, iryo[i].s_name); } printf("出力後\n"); printf("%d",sizeof(struct aaa)); return 0; } としたら、エラーは出ませんが、実行すると何も表示されませんでした。

  • C言語で分からない部分がいくつかあります。

    長文になります。 市のデータ(cities.txt)を対象として、以下の各機能を持ったプログラムを作成しました。 1.情報の登録と一覧表示 2.情報の削除 3.cities.txt からの情報の読み込み 4.citiesDB.txtへのリスト内容の書き出し 5.人口でソート #include <stdio.h> #include <stdlib.h> #include <string.h> #define STRLEN 32 #define BUF_LEN 128 #define CITYDB_R_FILE "cities.txt" // 読み込み用ファイル #define CITYDB_W_FILE "citiesDB.txt" // 書き出し用ファイル struct cities{ char pref[STRLEN]; char city[STRLEN]; int popl; float area; float dens; char founded[STRLEN]; struct cities *next; }; struct cities *root=NULL; // rootへのポインタは大域変数として定義 void *mymalloc(size_t sz){ void *p = (void *)malloc(sz); if(p == NULL){ fprintf(stderr,"ERR: Can't malloc memory %d bytes.",(int)sz); exit(1); } memset(p,0,sz); return p; } void showCity(struct cities *c, FILE *fp){ fprintf(fp,"%s\t%s\t%d\t%.2f\t%.2f\t%s\n", c->pref, c->city, c->popl, c->area, c->dens, c->founded); } struct cities *genNewCityCell(char *pref, char *city, int popl, float area, float dens, char *founded ){ struct cities *c; c = mymalloc(sizeof(struct cities)); // メモリを確保した c に対して、値を代入する return c; } void showList(FILE *fp){ struct cities *cur= root; while(cur != NULL){ showCity(cur,fp); cur = cur->next; } } void saveList(){ // 書き込み用のファイルを開き、そのファイルポインタ fp に対して、 // showList(fp) を呼ぶ。 void showList() は12行上で定義している printf("File saved to %s\n",CITYDB_W_FILE); } struct cities *line2City(char *buf){ struct cities *c=NULL; int popl; char pref[STRLEN], city[STRLEN], founded[STRLEN]; float area, dens; sscanf(buf, "%s %s %d %f %f %s", pref, city, &popl, &area, &dens, founded); c = genNewCityCell(pref,city,popl,area,dens,founded); return c; } void addCity(struct cities *c){ struct cities **cur= &root; /* rootから順にたどって,末尾に挿入する */ } void inputStr(char *buf,int len){ fgets(buf,len,stdin); buf[strlen(buf)-1]='\0'; } void addNewCity(){ char buf[BUF_LEN] = ""; struct cities *c; while(strlen(buf)<=0){ printf("Input one line:\n"); inputStr(buf, BUF_LEN); } if(strncmp(buf, "Prefecture", 10) == 0) return; c = line2City(buf); addCity(c); } void deleteCityFromList(char *delcity){ /* 順にたどり,当該項目を削除する. addCity() も同様. */ } void deleteCity(){ char buf[STRLEN]; showList(stdout); printf("Select Delete City Name:"); inputStr(buf, STRLEN); deleteCityFromList(buf); } void readListFILE(FILE *fp){ char buf[BUF_LEN]; struct cities *c; while( fgets(buf,BUF_LEN,fp) != NULL){ if(strncmp(buf, "Prefecture", 10) == 0) continue; c = line2City(buf); if(c != NULL) addCity(c); } } void readList(){ /* ファイルCITYDB_R_FILEを読み取り用で開く ファイルが開けない場合のエラー処理 readListFILE(fp); ファイルをクローズ */ printf("File loaded\n"); } void insertCityByPopl(struct cities *sc){ struct cities **cur= &root; /* 順にたどり、挿入すべき箇所に sc を挿入 */ } void sortList(){ struct cities *cur,*fr; cur = root; root = NULL; while(cur != NULL){ insertCityByPopl(genNewCityCell(cur->pref, cur->city, cur->popl, cur->area, cur->dens, cur->founded)); fr = cur; cur = cur->next; free(fr); } showList(stdout); } int main(int argc, char *argv[]){ char buf[BUF_LEN]; while(1){ printf("Menu(a:add, d:delete, l:list, s:sort, w:write file, r:read file q:quit):\n"); fgets(buf,BUF_LEN,stdin); switch(buf[0]){ case 'a': addNewCity(); break; case 'd': deleteCity(); break; case 'l': showList(stdout); break; case 's': sortList(); break; case 'w': saveList(); break; case 'r': readList(); break; case 'q': exit(0); break; } } } ただ、コメントのある部分の関数が完成できません・・・・ どなたか教えてください。

  • C言語の使い方を教えてください。-C言語入門者

    C言語のプログラムの処理の対象となるファイルはどこに保存したらよいのでしょうか?たとえば下記のプログラムで #include <stdio.h> #include <stdlib.h> #include <string.h> void main(void) { char *line[100], *buf; int i = 0, len, lines; FILE *fp; fp = fopen("textfile.txt", "r"); buf = calloc(128, sizeof(char)); while (i < 100 && fgets(buf, 128, fp) != NULL) { len = strlen(buf); line[i] = calloc(len + 1, sizeof(char)); strcpy(line[i], buf); i++; } fclose(fp); lines = ((i <= 100) ? i :100); free(buf); for(i = 0; i < lines; i++) printf("%s", line[i]); for(i = 0; i < lines; i++) free(line[i]); } で [textfile.txt]という名のファイルをマイドキュメントやコンパイラーを保存しているのと同じ領域に保存してコンパイラーを実行しても所要の結果が得られません。テキストにはプログラムの作り方しか書いてありません。

  • c言語つくってみました

    #include<stdio.h> #define N 5 struct MEMBER{ int no; char name[8+1]; int run; int jump; int power; int sum; double avg; }; void Calc_Sum(struct MEMBER *data) { data->sum=data->run+data->jump+data->power; return(0); } void Calc_Avg(struct MEMBER *data) { data->avg=data->sum/3.0; return(0); } void Display_Data(struct MEMBER data) { printf("---判定---\n"); printf("背番号:%5d\n",data.no); printf("名前:%5s\n",data.name); printf("走力 :%5d 点数\n",data.run); printf("跳躍力:%5d 点数\n", data.jump); printf("筋力 :%5d 点数\n", data.power); printf("総計 :%5d 点数\n", data.sum); printf("平均 :%5.1f 点数\n", data.avg); return(0); } int main(void) { int i; struct MEMBER member[N] ={{51,"イチロー",95,95,80,0,0}, {55,"松井秀喜",70,80,90,0,0}, {18,"松坂大輔",75,75,80,0,0}, {18,"黒田博樹",80,85,85,0,0}, {19,"上原浩治",85,85,85,0,0}, }; struct MEMBER *p=member; /*総計の算出*/ for(i=0;i<N;i++) Calc_Sum(p+i); /*平均の算出*/ for(i=0;i<N;i++) Calc_Avg(p+i); /*結果の出力:*/ for(i=0;i<N;i++) Display_Data(member[i]); return(0); } 以上のようなのc言語をつくりました。 他に関数を2つ使用しなければならないのですが アドバイスよろしくお願い致します。

  • 構造体の構造体 引数

    構造体の中の構造体の関数の引き渡し方法がわかりません。 下記ソースで試したのですが、うまくいきませんでした。 助言お願いいたします。 //repo.c #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #define NUM 20 #define MAX 15 struct seiseki{ float shu[3]; }; struct seito{ char name[NUM]; int age; struct seiseki kekka; }; void input(struct seito *p); void s_input(struct seiseki *p); void ss_input(struct seiseki *data); int main(){ int i; struct seito data[2]; for(i=0;i<2;i++){ printf("------------------------------\n"); printf("%d人目",i+1); input(&data[i]); } printf("%f\n",data[0].kekka.shu[0]); printf("%f\n",data[0].kekka.shu[1]); printf("%f\n",data[0].kekka.shu[2]); //data[1]に格納できない。 printf("%f\n",data[1].kekka.shu[0]); printf("%f\n",data[1].kekka.shu[1]); printf("%f\n",data[1].kekka.shu[2]); return 0; } void input(struct seito *p){ printf("名前->"); scanf("%s",p->name); printf("年齢->"); scanf("%d",p->age); s_input(&(p->kekka)); } void s_input(struct seiseki *data){ printf("国語->"); ss_input(data); printf("算数->"); ss_input(data); printf("英語->"); ss_input(data); } //下記関数で成績をchar型で受け取り、数値化したい。 void ss_input(struct seiseki *data){ char p[100]; int i=0; static int o=0; scanf("%s",p); while( p[i] != '\0'){ if(isdigit(p[i])==0){ printf("再入力してください"); scanf("%s",p); } i++; } data->shu[o]=atof(p); printf("%f\n",data->shu[o]); o++; }

  • 構造体の配列のアロケート等の方法

    基本的な事かもしれないのですが、 構造体の配列をダブルポインタで返すような関数を作成したいのですが、アロケートの仕方と、そもそも配列をダブルポインタで扱う方法が良く分かってないのかもしれません。 どなたかご教授頂けないでしょうか? Webで調べてもなかなか合ったものが見つからないため、こちらに質問させて頂きました。 イメージしているものを↓に途中まで作ってみました。これも合っていない部分があるかもですが。。。 要はアロケートして構造体の配列を作成する部分と、それをfor文で回して参照する方法が、分かっていない主なところです。 #include <stdio.h> #include <memory> typedef struct member{   int  id;   char*  name; } *member_t; int get_result(member_t *pobj) {   member_t* obj = NULL;   obj = (member_t*)malloc(sizeof(member_t));   memset(obj, 0x00, sizeof(member_t));   char* nm = NULL;   char cnmtmp[] = "nakayama";   nm = (char*)malloc(strlen(cnmtmp)+1);   memset(nm, 0x00, strlen(cnmtmp)+1);   memcpy(nm, cnmtmp, strlen(cnmtmp));   obj->id = 100;   obj->name = nm;   *pobj = obj;   return 0; } int get_resultList(member_t **ppobj) {   /*    * ココ    */   return 0; } void main() {   member_t* obj = NULL;   get_resultList(&obj);   for(int i = 0;;){     /*      * ココ      */     printf("[%d]\n",i+1);     printf("ID : %d\n", ->id);     printf("NAME : %s\n", ->name);     free( ->name);     free( );   }   free(obj); } 長々とすみません。

  • C言語の構造体についての質問です。

    C言語の構造体についての質問です。 学校でC言語の授業を受けていて、課題が出たのですが、わかりませんでした。回答よろしくお願いします。 課題内容は、 配列を用いて以下の処理をおこなうプログラムを作成しなさい。 テキストファイルから番号、名前、英語、国語、数学3科目の得点を読み込む。 各自の3科目平均点を計算する。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MSTDNT 10 #define MNAMEL 10 #define MBFFRL 32 typedef struct student{ int id; char name[MNAMEL]; int engl; int jpan; int math; float mean; } STDNT; void readin(STDNT *p); void disply(STDNT *p); void dscend(STDNT *p); int main(void){ STDNT students[MSTDNT]; readin(students); disply(students); printf("reorder by descending mean\n"); dscend(students); disply(students); return 0; } //_(1)_番号、名前、英語、国語、数学の得点を読込む //_(2)_各自の3科目平均点を計算する void readin(STDNT *p){ int i; FILE *file; char *fnm="h109113.txt"; char bffr[MBFFRL]; if((file=fopen(fnm,"r"))==NULL){ printf("ファイル%sはありません\n",fnm); exit(1); } for(i=0;i<MSTDNT;i++){ if(fgets(bffr,MBFFRL,file)!=NULL){ printf("ファイル%sは不完全です\n",fnm); printf("No.%dレコード?\n",i); exit(2); } p->id=atoi(strtok(bffr,",\n")); strcpy(p->name,strtok(NULL,",\n")); p->engl=atoi(strtok(NULL,",\n")); p->jpan=atoi(strtok(NULL,",\n")); p->math=atoi(strtok(NULL,",\n")); p->mean=(float)(p->engl+p->jpan+p->math)/3; } fclose(file); return; } //成績表の格納状況を表示する void disply(STDNT *p){ int i; printf("番号 名前 英語 国語 数学 平均\n"); for(i=0;i<MSTDNT;i++){ printf("%4d %4s %4d %4d %4d %4.1f\n", p->id,p->name,p->engl,p->jpan,p->math,p->mean); } return; } //(3)3科目の平均点の高い順に並び変える void dscend(STDNT *p){ int i,j; STDNT tmp; for(i=0;i<MSTDNT-1;i++){ for(j=i+1;j<MSTDNT;j++){ if(p[i].mean>p[j].mean){ tmp=p[i];p[i]=p[j];p[j]=tmp; } } } return; } 出力がちゃんとできません。よろしくお願いします。

  • ファイル操作やポインタ、構造体について(C言語)

    C言語の課題で詰まってしまいました。宜しければ助言を宜しくお願いします。 コマンド選択で,0) 終了,1) 追加,2) 検索(id),3)変更 が行える学生成績管理プログラムを作成する。 データは,学生の番号 名前 GP 総単位数 形で学生のデータを持っているファイルである。 #include<stdio.h> #include<stdlib.h> #include<string.h> struct student{ int id; char name[25]; int gp; int credit; }; void add(char *, struct student);//追加 int search(char *, struct student *);//検索 void change(char *, struct student);//指定したidの学生の情報を変更 main(int argc,char *argv[]) { FILE *fp; int i = 0; int num; struct student students; if(argc == 1){ printf("set filename\n"); return 1; } while(1) { printf("1)add 2)search 0)quit "); scanf("%d",&num); if(num == 0) break; /* 追加 */ if(num == 1) { printf("id name gp credit ? "); scanf("%d %s %d %d", &students.id, students.name, &students.gp, &students.credit); add(argv[1], students); } /* 検索 */ if(num == 2) { printf("id ? "); scanf("%d", &students.id); if(search(argv[1],&students)){ printf("%d %s %d %d\n", students.id, students.name, students.gp, students.credit); } else{ printf("ID %d Not Found.\n",students.id); } } if(num == 3){ //変更 } } } /* 追加ルーチン */ void add(char *filename, struct student students) { FILE *fp; if((fp = fopen(filename, "a")) == NULL){ printf("can't open %s\n", filename); exit(1); } fprintf(fp,"%d %s %d %d\n", students.id, students.name, students.gp, students.credit); fclose(fp); } /* 検索ルーチン */ int search(char *filename, struct student *students) { FILE *fp; int id; char name[25]; int gp; int credit; if((fp = fopen(filename, "r")) == NULL){ printf("can't open %s\n", filename); exit(1); } while(fscanf(fp,"%d %s %d %d", &id, name, &gp, &credit) != EOF) { if(id == students->id){ students->id = id; strcpy(students->name ,name); students->gp = gp; students->credit = credit; return 1; } } return 0; fclose(fp); } /* 変更ルーチン */ void add(char *filename, struct student students){ } ------------ここまで------------ ファイルの操作での入出力は"a"や"r"、また"w"を利用するのかとも思いましたが、 指定したIDの内容を書き換えるにはポインタを2つ使う方法しか思いつかないのですが、与えられた問題で、変更のプロトタイプは void change(char *, struct student); となっていて、どうやるのかまったく見当もつきません。 稚拙な文で伝わりにくいかもしれませんが、 変更のやり方についてご教授願います。 見難くて申し訳ありません。 どうか宜しくお願いします。

  • C言語 構造体の並び替え 

    #include<stdio.h> typedef struct{ char mozi[10]; char namae[30]; }PE; void input_profile(PE *p,int *a); void printf_profile(PE *p,int *a); int main(void) { int i=0; PE c[999]; input_profile(c,&i); return 0; } void input_profile(PE *p,int *a){ int c,b; for(b=0;999>b;b++) { printf("名前を入力\n"); scanf("%s",(p+b)->namae); printf("文字を入力\n"); scanf("%s",(p+b)->mozi); printf("入力を終えるなら0を入力してください\n続けるなら、それ以外の数字を入力してください\n"); scanf("%d",&c); if(c==0)break; } b++; *a=b; printf_profile(p,a); } void printf_profile(PE *p,int *a) { int b; for(b=0;*a>b;b++) { printf("NO%d\n",b+1); printf("文字%s\n",(p+b)->mozi); printf("名前%s\n",(p+b)->namae); } } このプログラムを 自分で関数を作って データ一覧をmoziのアルファベット順に表示するように書きなおしたいんですけど どうなるのでしょうか? どうか教えてください

専門家に質問してみよう