• ベストアンサー

ノード作成時、特別な処理を行わないプログラム

ファイルから読み込んだデータを構造体へ格納するプログラムを作成したのですが、最初のノードを作成する際にも特別な処理を行わないプログラムを作成するように指示されて、どのようにしていけば良いのかわからず困っています。 良ければどなたかヒントなどご指導いただける方いましたらよろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define NAME_LENGTH 20 /* 名前を格納する文字列の長さ */ #define ADDRESS_LENGTH 30 /* 住所を格納する文字列の長さ */ /* 構造体の定義 */ typedef struct p_tag{ /* タグ */  char name[NAME_LENGTH]; /* 名前 */  char address[ADDRESS_LENGTH]; /* 住所 */  int age; /* 年齢 */  struct p_tag *next; /* 自分自身の型へのポインタ変数 */ } personal_t; /* 住所データ型の定義 */ /*  リスト構造の新しいノードを作成する関数 makeNewNode()  引数   char *aName 名前(文字列)の先頭アドレス   char *aAddr 住所(文字列)の先頭アドレス   int aAge 年齢 返値   personal_t * 新しく作成したノードの先頭アドレス */ personal_t *makeNewNode(char *aName, char *aAddr, int aAge) {  personal_t *pNewData;  /*** personal_t 型のメモリ領域を確保 ***/  pNewData = (personal_t *) malloc( sizeof(personal_t) );  /*** 氏名・住所・年齢のデータを設定する   nextはNULLにする ***/  strcpy( pNewData->name, aName );  strcpy( pNewData->address, aAddr );  pNewData->age = aAge;  pNewData->next = NULL;  return( pNewData ); } /*  main()  引数   なし  返値   int 正常終了の時 0    異常終了の時 -1 (ファイルの読み込み失敗など) */ int main( void ) {  personal_t *pTop = NULL; /* リストの先頭ノードのアドレスを持つ変数 */  personal_t *pNew; /* 新しく作成したノードのアドレスを持つ変数 */  personal_t *pNow; /* 現在見ているノードのアドレスを持つ変数 */  FILE *fp; /* データファイルのファイルポインタ */  char name[ NAME_LENGTH ]; /* ファイルから読み込んだ名前を一時的に保持する変数 */  char address[ ADDRESS_LENGTH ]; /* ファイルから読み込んだ住所を一時的に保持する変数 */  int age; /* ファイルから読み込んだ年齢を一時的に保持する変数 */  /*** データファイル exer4.txt を読み込み用に開く.   ファイルが開けなかった場合,エラーメッセージを表示し異常終了する.***/  fp = fopen( "exer4.txt", "r" );  if ( NULL == fp ) {   printf( "ファイルが開けませんでした.\n" );   return( -1 );  }  /* データファイルから1件目のデータを読み込む   ファイルの終わり(返値がEOF)ならばエラーメッセージを表示し異常終了する.*/   if ( EOF == fscanf( fp, "%s %s %d", name, address, &age ) ) {   printf( "データの読み込みに失敗しました.\n" );    fclose( fp );   return( -1 );  }  /*** 1件目のデータを格納するために,最初のノードを作成する ***/  pTop = makeNewNode( name, address, age );  /*** 現在見ているノードを最初のノードにセットする ***/  pNow = pTop;  /* 2件目以降のデータをファイルの最後(EOF)まで読み込み,   新しく作成したノードに格納していく */  while( EOF != fscanf( fp, "%s %s %d", name, address, &age ) ) {   /*** 新しいノードを作成 ***/   pNew = makeNewNode( name, address, age );  /*** 現在見ているノードに新しいノードを連結し,新しいノードを現在見ているノードとする ***/   pNow->next = pNew;   pNow = pNew;  }  /* ファイルを閉じる */  fclose( fp );  /*** リストを終わりまでたどりながらデータを表示する ***/  /* 現在見ているノードを最初のノードにセットする */  pNow = pTop; /* pTop がないと最初のノードのアドレスが分からなくなる */  /* リストの終わりまでたどり着くと,pNowがNULLになる */  while( pNow != NULL ) {  /* 出力 */   printf( "%-10s %-10s %d\n", pNow->name, pNow->address, pNow->age);   /* 次のデータへ */   pNow = pNow->next;  }  return( 0 ); }

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

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

> 最初のノードを作成する際にも特別な処理を行わないプログラムを > 作成するように指示されて の意味は 1件目の作成とそれ以後を1回の処理の記述でしなさいといったことでしょう pNew = makeNewNode( name, address, age ); if ( pTop == NULL ) {   // 初回のノードの場合   pTop = pNew; } else {   pNow->next = pNew; } pNow = pNew; といった具合で処理可能なように思います

iriiri_001
質問者

お礼

なるほど。 特別な処理を行わないという解釈がいまいちわからなかったのですが、 一回の処理で記述すれば上手くいきそうですね。 参考になりました。ありがとうございます

その他の回答 (3)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

ポインタのポインタを使う.

  • plh
  • ベストアンサー率50% (4/8)
回答No.3

新しいノードをリストの最後に追加する関数を作成して、これを繰り返し呼ぶようにすれば良いと思います。 makeNewNode() の代わりに次のようなプロトタイプの関数を作成するということです。 personal_t* Push_back_new_node(personal_t* pperson, char* acName, char* acAddr, int iAge); pperson が 0 なら、新しいノードを作成して返せばよいし、非 0 なら、リストを最後まで手繰ってから新しいノードを追加すればよいということです。 上記を使って、main() のコードは次のようになるでしょう。 personal_t* ppersonTail = 0; while (データを 1 行分入力する) {   ppersonTail = Push_back_new_node(ppersonTail, acName, acAddr, iAge); } C でプログラムしなくてはならなくて、教育課程の課題なのであれば上記のような感じかと思います。 一点注意としては malloc() で確保したメモリは、正しく開放した方が良いですね。C ではこの辺りがスマートに書けないので、出来れば C++ を使える方が良いのですが。 C++ を使っても良くて、仕事ならば、STL の list とか vector を使うべきですが、これでは課題解決にならないんでしょうね。 STL は C++ 標準ライブラリの一部なので、C++ を使っても良いのならば教育課程の課題であったとしても list を使用することは違反ではないでしょう。 むしろ、標準ライブラリにある list 機能を自作するのは車輪を再発明するのに似ているとも言えます。 参考までに C++ で回答に近いものを書くと次のようになります。 #include <cstdio> #include <list> #include <string> using namespace std; struct CPerson {   string m_strName;   int  m_iAge;   CPerson(const string& rstrName, int iAge) : m_strName(rstrName), m_iAge(iAge) {} }; int main() {   list<CPerson> listperson;   FILE* pfile = fopen("D:\\Desktop\\Data.txt", "r");   if (!pfile) { return -1; }   int iAge = 0;   char acName[1000];   while (fscanf(pfile, "%s %d", acName, &iAge) != EOF) {     listperson.push_back(CPerson(acName, iAge));   }   fclose(pfile);   {for (list<CPerson>::iterator itperson = listperson.begin(); itperson != listperson.end(); itperson++) {     printf("%-10s %d\n", itperson->m_strName.c_str(), itperson->m_iAge);   }}   return 0; } list には push_back() という関数があるので、これを使うだけです。Push_back_new_node() を作る必要が無いということですね。 list 自体が pTop、pNew、pNow などにあたるものを全て管理しているので、あとは何でもありということになります。 ご参考にとどめてください。

iriiri_001
質問者

お礼

非常に専門的な回答ありがとうございます。 まだ習っていなくわからない部分も多いですが、今後の参考にさせていただきます。ありがとうございました

回答No.2

 頭にダミーのノードを置く。

関連するQ&A

  • 双方向リストの関数

    双方向リストにデータファイルから読み込んだ氏名と成績のデータを追加し,リストの末尾から順にデータを表示するプログラムを作成したのですが、insertLast() 関数を用いて末尾ノードの後ろに新しいノードを連結するという部分をどのようにして良いのかわからず困っています。 どのように記述して良いのかわからなかった部分を/*** ***/のコメントで示してあります。 どなたかアドバイスやヒント、その他の指摘などご教授してくださる方いましたらよろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define NAME_LENGTH 20 /* 名前を格納する文字列の長さ */ /* 双方向リストのノードとなる構造体の定義 */ typedef struct sList{  struct sList *prev; /* 前のノードのアドレス */  char name[NAME_LENGTH]; /* 名前 */  char grade; /* 成績 */  struct sList *next; /* 次のノードのアドレス */ } sNode; /* この構造体を sNode型 と定義する */ /* 双方向リストの先頭と末尾を格納するための構造体 */ typedef struct {  sNode *firstNode; /* リストの先頭ノードのアドレス */  sNode *lastNode; /* リストの末尾ノードのアドレス */ } manageList; /*  双方向リストの末尾にノードを追加する関数 insertLast()  引数   manageList *list リストの先頭・末尾ノードを管理する構造体のアドレス   sNode *node 末尾に追加したいノードのアドレス  返値   なし */ void insertLast(manageList *list, sNode *node ) {  /*** リストの末尾にノードを追加する ***/  return; } /*  双方向リストの新しいノードを作成する関数 makeNewNode()  引数   char *aName 名前(文字列)の先頭アドレス   char aGrade 成績  返値   sNode * 新しく作成したノードの先頭アドレス */ sNode *makeNewNode(char *aName, char aGrade ) {  sNode *pNewData;  /* sNode 型のメモリ領域を確保 */  pNewData = (sNode *) malloc( sizeof(sNode) );  /* 名前と成績のデータを設定する */  strcpy( pNewData->name, aName );  pNewData->grade = aGrade;  pNewData->prev = NULL;  pNewData->next = NULL;  return( pNewData ); } /*  main()  引数   なし  返値   int 正常終了の時 0     異常終了の時 -1 (ファイルの読み込み失敗など) */ int main( void ) {  manageList list; /* リストの先頭・末尾ノードのアドレスを持つ構造体 */  sNode *pNew; /* 新しく作成したノードのアドレスを持つ変数 */  sNode *pNow; /* 現在見ているノードのアドレスを持つ変数 */  FILE *fp; /* データファイルのファイルポインタ */  char name[ NAME_LENGTH ]; /* ファイルから読み込んだ名前を一時的に保持する変数 */  char grade; /* ファイルから読み込んだ成績を一時的に保持する変数 */  /* 初期状態では先頭・末尾ノードともNULL */  list.firstNode = NULL;  list.lastNode = NULL;  /* データファイル exer6.txt を読み込み用に開く.    ファイルが開けなかった場合,エラーメッセージを表示し異常終了する.*/  fp = fopen("exer6.txt","r");  if(NULL == firstNode){   printf( "ファイルが開けませんでした. \n" );   return( -1 );  }  /* データをファイルの最後(EOF)まで読み込み,双方向リストにデータを追加する */  while( EOF != fscanf( fp, "%s %c", name, &grade ) ) {   /* 新しいノードを作成 */   pNew = makeNewNode( name, grade );   /*** insertLast() 関数を用いて末尾ノードの後ろに新しいノードを連結する ***/   pNow->next = pNew ;   pNew->prev = pNow ;   pNow = pNew ;  /* ファイルを閉じる */  fclose( fp );  /* 現在見ているノードを末尾ノードにセットする */  pNow = lastNode  /* 末尾のノードから前のノードへたどりながらデータを出力する */  while( NULL != pNow ) {   /* 出力 */   printf( "%s %c\n", pNow->name, pNow->grade );   /* 現在見ているノードを一つ前のノードにする */   pNow = pNow->prev;  }  return( 0 ); }

  • C言語のプログラムを書いたのですが上手く動きません

    C言語の練習問題をプログラミングしたのですが、上手く動きません。 コンパイルはできるのですが、実行すると「Segmentation fault(core dumped)」となります。 問題は、コマンドライン引数としてファイル名を指定したテキストファイルから読み込んだデータを,双方向リストに格納し,順番に表示するというものです。 テキストファイルは 10T5001 C 10T5002 A 10T5003 B 10T5004 C 10T5005 D 10T5006 B 10T5007 A 10T5008 D このように、IDとランクをランクABCDをスペースで区切ったもので、これをランクAから順番に表示させます。 上手く動けば ID: 10T5002, grade: A, ID: 10T5007, grade: A ID: 10T5003, grade: B ID: 10T5006, grade: B ID: 10T5001, grade: C ID: 10T5004, grade: C ID: 10T5005, grade: D ID: 10T5008, grade: D と表示されるはずなんですが・・・ これが僕の書いたプログラムです(長いです。ごめんなさい) #include <stdio.h> #include <stdlib.h> #include <string.h> #define ID_LENGTH 8 /* IDの長さ+ナル文字 */ #define EFOPEN -1 #define ENOMEM -2 #define EINVAL -3 /* 双方向リストのノード */ typedef struct sList /* タグ */ { char id[ID_LENGTH]; /* ID */ char grade; /* ランク*/ struct sList *prev; /* 前のノードのアドレス */ struct sList *next; /* 次のノードのアドレス */ } sNode; /* 双方向リストのノードを作成する関数 makeNewNode() 作成したノードのprevとnextはNULLにする 引数 ・ノードに格納するID ・ノードに格納するランク(A/B/C/D) 戻値 作成したノードの先頭アドレス.メモリの確保に失敗した場合はNULL */ sNode *makeNewNode(char *id, char grade) { sNode *pNewNode; pNewNode = (sNode*)malloc(sizeof(sNode)); if(pNewNode != NULL) { strncpy(pNewNode->id, id, ID_LENGTH-1); pNewNode->grade = grade; pNewNode->prev = NULL; pNewNode->next = NULL; } return pNewNode; } /* 引数で渡された任意のノードの後ろに新しいノードを追加する関数 insertNext() 引数 ・後ろにノードを追加したいノードの先頭アドレス ・追加するノードの先頭アドレス 戻値 なし */ void insertNext(sNode *node, sNode *newNode) { if(node->next == NULL) //一番後ろに追加する場合 { node->next = newNode; newNode->prev = node; } else //まん中に挿入する場合 { newNode->prev = node; newNode->next = node->next; node->next->prev = newNode; node->next = newNode; } } /* main() 引数 int argc コマンドライン引数の数 char *argv[] 与えられたコマンドライン引数の文字列の先頭アドレスの配列 戻値 int 正常終了の時 0 以下の場合は異常終了し,括弧内の値を返す データファイルが開けなかった場合(EFOPEN) makeNewNode()でメモリが確保できなかった場合(ENOMEM) 引数の数が正しくない場合(EINVAL) */ int main(int argc, char *argv[]) { sNode *top; /* リストの先頭ノードのアドレスを保持する変数*/ sNode *new; /* 新しく作成したノードのアドレスを保持する変数 */ sNode *now; /* 現在見ているノードのアドレスを保持する変数 */ FILE *fp; /* データファイルのファイルポインタ */ char id[ID_LENGTH]; /* ファイルから読み込んだIDを一時的に保持する変数 */ char grade; /* ファイルから読み込んだランクを一時的に保持する変数 */ /* コマンドライン引数の数をチェックする 数に過不足があれば,使い方を表示し,異常終了する */ if(argc != 2){ printf("Usage: %s datafilename.\n", argv[0]); return EINVAL; } /* データファイルを読み込み用に開く ファイルが開けなかった場合,エラーメッセージを表示し異常終了する */ fp = fopen(argv[1], "r"); if(NULL == fp){ printf("No such file %s.\n", argv[1]); return EFOPEN; } /* リストの先頭に番兵を立てる */ new = makeNewNode("Banpei", 'A'-1); if (new == NULL){ printf("Error: cannot allocate memory\n"); return ENOMEM; } top = new; /* データファイルから1行ずつデータを読み込み,ランク順にリストに追加していく 既にリストの先頭には番兵ノードがある点に注意 */ while(EOF != fscanf(fp, "%s %c", id, &grade)){ new = makeNewNode(id, grade); if(new == NULL){ printf("Cannot allocate memory.\n"); return EFOPEN; } if(top->next == NULL){ //リストが空の場合 insertNext(top, new); } else{ now = top; while(new->grade > now->grade){ now = now->next; } insertNext(now, new); } } /* できあがったリストの内容を先頭から順に表示する ただし,番兵ノードは表示しない */ now = top; while(now != NULL){ printf("ID: %s, grade: %c\n",now->id, now->grade,); now = now->next; } /* リストのノードを全て(番兵ノードも含む)解放し,リストを空にする */ now = top; while(now->next != NULL){ free(now->prev); now = now->next; } free(now); fclose(fp); return (0); } まだまだ練習中なもので、かなり拙いものだと思いますが、とりあえずまずはプログラム動くようにしたいです。 よろしくお願いします。

  • PHPのリロード時の処理

    PHPのリロード時の処理 PHPプログラム初心者です。 掲示板のプログラムを作成しております。 以下のコードで、リロード時、自動で投稿ボタンが押されてsubmitしてしまいます。 自分で考えた解決策としては、下記のwriteDate()内で、条件を入れることです。 $_GET['personal_name'];のデータを変数に保持し、次にリロードされた時同じものが返ってきら、writeDate()内の処理をしないという方法です。 このときの変数の保存の仕方が解りません。 ご存じの方がおられましたら教えてください。 <?php if($_SERVER["REQUEST_METHOD"]=="GET"){ writeData(); } readData(); function readData(){ $keijban_file='keijiban.txt'; $fp=fopen($keijban_file,'rb'); if($fp){ if(flock($fp,LOCK_SH)){ while(!feof($fp)){ $buffer=fgets($fp); print($buffer); } flock($fp,LOCK_UN); }else{ print('ファイルロックに失敗しました'); } } fclose($fp); } function writeData(){ //--------ここで同じ書き込みデータがあればreturnしたい。------- $t=$_GET['personal_name']; $personal_name=$_GET['personal_name']; $contents=$_GET['contents']; $contents=nl2br($contents); $data="<hr>\r\n"; $data=$data."<p>[投稿者:".$personal_name."]</p>"; $data=$data."[内容]"; $data=$data."<p>".$contents."</p>"; $keijban_file='keijiban.txt'; $fp=fopen($keijban_file,'ab'); if($fp){ if(flock($fp,LOCK_EX)){ if(fwrite($fp,$data)===FALSE){ print('ファイル書き込みに失敗しました'); } flock($fp,LOCK_UN); }else{ print('ファイルロックに失敗しました'); } } $data=null; fclose($fp); } ?>

    • ベストアンサー
    • PHP
  • プロミング(C++)の質問です。

    プログラミングの宿題で、『5人分の年齢,身長,名前の順にキー ボードからファイルに保存するプログラムを作成せよ』という課題 がでました。以下のように書いたのですが、『書き込むファイルはあるが読み込むファイルがない』といわれたのですが、よくわかりません。 どのように改善したらよいのでしょうか? #include<stdio.h> struct person{ int age; float height; char name[40]; }; int main(void){ person a[5]; FILE *fp; if ((fp=fopen("kadai.dat","w"))==NULL){ fprintf(stderr,"File open failed.\n"); return 1; } int t; for(t=0;t<5;t++){ printf("age,height,name \n"); if(scanf("%d %f %s",&a[t].age,&a[t].height,a[t].name)<3); break; printf("%d %f %s \n",a[t].age,a[t].height,a[t].name); fprintf(fp,"%d %e %s \n",a[t].age,a[t].height,a[t].name); } fclose(fp); return 0; }

  • ファイル読込時に構造体の文字列ポインタに割当てたいと

    ファイル読込時に構造体の文字列ポインタに割当てたいと思っています。 (new 演算子を使用します。) 文字列の長さが不定です。 どうすれば、文字列の長さを知ることができますか? 以下のようなところまでは作れましたが、 困っています。 void loaddata()のfscanf関数の部分です。 ほかにも関数の void outputdata() void deletedata() がありますが、長いので省略しました。 ********************************************************** #include<stdio.h> #include<string.h> class data { public: struct basic { char *name; int age; struct basic *next; }; private: struct basic *base; struct basic *base_top; int cnt; public: data::data() { cnt=0; } void inputdata(char *name,int age) { if(cnt==0) { base=new basic; base_top=base; base->age=age; int len=strlen(name); base->name=new char[len+1]; strcpy(base->name,name); cnt++; } else { base->next=new basic; base=base->next; base->age=age; int len=strlen(name); base->name=new char[len+1]; strcpy(base->name,name); cnt++; } } void savedata() { base=base_top; FILE *fp; fp=fopen("dat.txt","w"); for(int i=0;i<cnt;i++) { fprintf(fp,"%s\t%d\n",base->name,base->age); base=base->next; } fclose(fp); } void loaddata() { if(cnt!=0){deletedata();} cnt=0; FILE *fp; fp=fopen("dat.txt","r"); while(1) { fscanf(fp,"%s\t%d\n",base->name,base->age); } } };

  • CSVファイルを更新する処理

    CSVに追加や削除、一覧表示、更新をする処理を書いたのですが 更新処理だけうまくいかずに躓いています。 readメソッドのreturn $files;のところで下記の syntax error, unexpected '$files' (T_VARIABLE)というエラーが出てしまいます。 なぜエラーが出ているか教えていただけるとありがたいです。 <?PHP function con($hantei, $num, $name, $age, $address){ $data = [ $num, $name, $age, $address ]; $datas = [$data]; // 追加 if($hantei === 'add'){ $fp = fopen('data.csv', 'a'); foreach($datas as $data) { $line = implode(',' , $data); fwrite($fp, $line . "\n"); } fclose($fp); //更新 } elseif ($hantei === 'update') { function read() { $FILENAME = 'data.csv'; $file = fopen($FILENAME, 'r'); while($data = fgetcsv($file)) { $files[] = $data; }   fclose($file);   return $files; } function replace($num, $name, $age, $address) { // read() $files = read(); $arr = array(); foreach($files as $key => $el) { // [0][a, b, c, d] // [1][a, b, c, d] if ($el[0] == $num) { // $arr[0][0] = $num ... $arr[$key] = array($num, $name, $age, $address); } else { $arr[$key] = array($el[0], $el[1], $el[2], $el[3]); } }    return $arr; } replace(); function write($arr){   $FILENAME = 'data.csv'; $file = fopen($FILENAME, 'w');   foreach ($arr as $v) {    fputcsv($file,$v); }    fclose($file); } $arr = replace($num, $name, $age, $address); write($arr); //削除 } elseif ($hantei === 'dalete') { $file = file('data.csv'); unset($file[$num]); file_put_contents('data.csv', $file); //一覧表示 } elseif ($hantei === 'list') { $fp = fopen('data.csv', 'r'); $readed = fread($fp, filesize('data.csv')); print_r($readed); fclose($fp); } } con('update', 1, 'name', 3, 'address');

    • 締切済み
    • PHP
  • 画像処理について・・・・・・・・・・・

    #include<stdio.h> #include<stdlib.h> #define X_SIZE 512 #define Y_SIZE 512 unsigned char DATA[Y_SIZE][X_SIZE]; unsigned char O_DATA[Y_SIZE][X_SIZE]; char input_file_name[256]=”Lenna.raw”; char output_file_name[256]=”Lenna_out.raw”; void heikin(){ int x,u; int temp; for(y=1;y<Y_SIZE-1;y++){ for(x=1;x<X_SIZE-1;x++){ temp=・・・・・・・・・・・・・・・・・・・・・・・・; O_DATA[x][y]=(unsigned char)temp; } } } Int main (){ FILE*fp; If((fp=fopen(input_file_name,”rb”))==NULL){ Printf(“ファイルオ-プンエラ-\n”); Return 1; } Fread(DATA,sizeof(DATA),1,fp); fclose(fp); heikin(); if((fp=fopen(output_file_name,”wb”))==NULL{ printf(“ファイルオ-プンエラ-\n”); return 1; } Fwrite(O_DATA,sizeof(O_DATA),1,fp); Fclose(fp); Return 0; } ソースコードをやっているのですが、後、・・・・・・・・・の所を入力して完成なんですが、苦戦してます。 処理の内容としましては、 1、入力画像Lenna.rawを読み込んで、 2、平均値フィルタをかけ、 3、Lenna_out.rawに書き出す(保存する)したいんですが、公式みたいなのを入れればいいのでしょうか? すみませんが、お願いします。

  • strtok

    strtokにて分解した文字を各変数に格納する場合 char *p; FILE *fp; char buf[1000]; if((fp = fopen("○","r"))==NULL){ return 0; } if(!fgets(buf,1000,fp)) return 0; strcpy(p, buf); number = strtok(p,","); class_type = strtok(NULL,","); name = strtok(NULL,","); subject = strtok(NULL,","); と一行の文字列を各変数に格納しています。 ファイルの一行は以下のような形式になっています。 1,A,山田,数学//番号,クラスタイプ,名前,得意教科 これで各値は変数に格納できています。 しかし このファイルはCSVファイルなのですが、空の欄があると 1,A,,数学というデータがbuf内に入っています。 この場合 number→1 class_type→A name→数学 と空欄の箇所が飛ばされてしまっています。 改善する方法がわからないのですが strtokを使わない方がいいのでしょうか?

  • ファイルの統合プログラム

    ----aaa.txt-------- name number band J0223 1.0 2.2 J0222 null 1.2 J0221 2.0 null J0224 2.0 2.0 ----bbb.txt--------- name time J0222 11.0 J0223 22.0 ----ccc.txt---------- name number J0222 20 J0221 J0223 10 ---望む結果------ name number band name time name number J0223 1.0 2.2 J0223 22.0 J0223 10 J0222 null 1.2 J0222 20 J0221 2.0 null J0221 J0224 2.0 2.0 上記のような中身の3つのファイル(各columnはタブで区切れられている)を用意して、aaa.txtの一列目の文字列とbbb.txt,ccc.txtの一列目の文字列が一致する行だけを抜き出してaaa.txtの各行のあとにくっつけるプログラムを書きたい(望む結果)のですが、どう書いていいわかりません.これまでは、下記のプログラムのようにいちいちcolumnの変数を定義して上記のような処理をしてきたのですが、今回扱うファイルはcolumnの数が多く(100個)、columnの変数を一つ一つ定義して書くのは非常大変になると思います.ですので、出来ればcolumnの数がわからなくともファイルを読みこませれば上記のような処理を行なってくれるプログラムが書きたいです.どなたかご教授いただけないでしょうか.回答よろしくおねがいします. 内容がわかりづらかったらすいません. ----------プログラム--------------- #include<stdio.h> int main(void) { FILE *fp ,*gp; int ret; char xl[30],nx1[30],xls[30],nx2[30],xlb[30],nb2[30]; fp=fopen("bbb.txt","r"); gp=fopen("aaa.txt","r"); while(fscanf (fp,"%s%s",xls,nx2)==2){ while(fscanf (gp,"%s%s%s%s",nx1,xl,xlb,nb2)==4){ ret=strcmp(xls,nx1); if(ret == 0){ printf("%s\t%s\t%s\t%s\t%s\t%s\n",xl,nx2,nx1,xl,xlb,nb2); } } rewind(gp); } fclose(fp); return 0; }

  • 電話番号を読み込むプログラムについて教えてください

    こちらには初めての質問です、よろしくお願いします。 C言語の基礎を独学で学習中の初心者です。 テキストファイルに、名前と電話番号をあらかじめ書き込んでおき、 検索したい人の名前を入力すると、電話番号が表示されるというプログラムについて教えてください。 1、名前は漢字で入力    (山野 桜) 2、電話番号は、半角で入力 (001234567\n) この様にして10人分のデータが、入力してあります。 実行時に名前を入力しても電話番号が表示されません。 エラーメッセージも出ません、プログラムに問題があるのか、作成したテキストファイルに問題があるのか判断できません。 アドバイスをお願いします。 #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char name[10][22]; char phone[10][13]; char input[21]; int loop; FILE *FP; if((FP = fopen("address.txt", "r")) == NULL) { printf("ファイルが開けません\n"); return(1); }     /*ファイルからデータを読み込む*/ for(loop = 0; loop < 10; loop++) { fgets(name[loop], 22, FP); name[loop][strlen(name[loop]) -1] = '0'; fgets(phone[loop], 13, FP); phone[loop][strlen(phone[loop]) -1] = '0'; } printf("電話番号を検索したい名前を入力してください\n"); gets(input); /*検索と表示*/ for(loop = 0; loop < 10; loop++) { if(strcmp(name[loop], input) == 0) {  printf("%sさんの電話番号は : %s\n", input, phone[loop]); } } return (0); }