• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:終了条件Ctrl+zについて,結果表示ついて(C言語))

終了条件Ctrl+zについて,結果表示ついて(C言語)

このQ&Aのポイント
  • 終了条件Ctrl+zについて,結果表示ついて(C言語)というセンセーショナルなタイトルを生成しました。
  • C言語のプログラムで、逆順につながったリストを作成する問題に取り組んでいます。しかし、終了条件のCtrl+zがうまく機能しておらず、入力時にも問題があります。また、変数の増減が制限されています。解決策を教えてください。
  • C言語のプログラムで逆順につながったリストを作成する問題に取り組んでいます。Ctrl+zによる終了条件が機能せず、入力時の並列化もうまくできません。また、変数の増減が制限されています。解決策を教えてください。

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

  • ベストアンサー
  • DT200
  • ベストアンサー率38% (63/164)
回答No.1

先ほど回答しようとしたところ締め切られていたのでここで改めて。 データを1行で入力しなければならない縛りが解けたみたいですね。 #include<stdio.h> #include<malloc.h> #include <unistd.h> #include <string.h> struct tfield{ char name[20]; char tel[20]; struct tfield *pointer; }; struct tfield *talloc(void); int main(void) { struct tfield *head,*p; char buffer[BUFSIZ]; head=NULL; while(1){ p=talloc(); if( p == NULL ){ printf( "メモリを確保できません。\n" ); _exit( 0 ); } printf( "name? " ); if( scanf( "%s", buffer ) == EOF ){ /* Ctrl+zだとscanfはEOFを返すので、このルートを通りループを抜ける */ /* 質問者はここで構造体へデータをいれようとしていますが、それはダメ */ free( p ); /* 使わないのでメモリを開放 */ break; } strcpy(p->name, buffer); printf( "tel? " ); if( scanf( "%s", buffer ) == EOF ){ /* nameと同じ */ free( p ); break; } strcpy(p->tel, buffer ); p->pointer = head; head = p; } printf( "\n" ); if( head != NULL ){ p=head; while( p != NULL ){ printf("%6s %s\n",p->name,p->tel); p=p->pointer; } /* 確保したメモリはきちんと開放する */ do{ p = head->pointer; free( head ); head = p; } while( head != NULL ); } return 0; } struct tfield *talloc(void) /*記憶領域の取得*/ { return (struct tfield *)malloc(sizeof(struct tfield)); }

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • リストの作成と出力(C言語)

    こんにちは<_ _> リストの問題についてなのですが出力と逆順に出力するプログラムで headと前のデータの間に新しいデータを追加するように作ったのですが 入力した値が帰ってきません・・・ http://www9.plala.or.jp/sgwr-t/c/sec15-5.html などを見て見ましたが原因がいまいちよくわかりません。 どなたか教えてください おねがいします<_ _> #include<stdio.h> #include<malloc.h> struct tfield{ char name[20]; char tel[20]; struct tfield *pointer; }; struct tfield *talloc(void); int main(void) { struct tfield *head,*p; char buffer[BUFSIZ]; head=NULL; while(1){ p=talloc(); if(scanf("%s",buffer) == EOF){ break; strcpy(p->name, buffer); } if(buffer == "^Z")break; printf(" "); if(gets(buffer) == EOF){ if(scanf("%s",buffer) == EOF){ break; strcpy(p->tel, buffer); } p->pointer=head; /*今までの先頭ポインタを次のポインタに*/ head=p; } p=head; while(p!=NULL){ printf("%6s %s\n",p->name,p->tel); p=p->pointer; } return 0; } struct tfield *talloc(void) /*記憶領域の取得*/ { return (struct tfield *)malloc(sizeof(struct tfield)); } 変数は変えるなとのことです。 あと、 「name tel name tel name tel ^z name tel name tel name tel」 と表示したいのですがCtrl+zを二回押さないとできません><、 当方プログラム1ヶ月の初心者です ご指導どうかよろしくお願いします<_ _>

  • C言語の自己参照型プログラムについて

    #include <stdio.h> #include <string.h> #include <stdlib.h> struct list { int key; /* キー */ char name[20]; /* 名前 */ struct list *next; /* 次のデータへのポインタ */ }; struct list *add_list(int key, char *name, struct list *head); void show_list(struct list *p); void free_list(struct list *p); int main(void) { struct list *head; /* 先頭ポインタ */ char name[20]; int key = 0; head = NULL; /* 先頭ポインタにNULLを設定 */ printf("キーと名前(MAX:19文字)を入力(終了:CTRL+Z)\n"); while (scanf("%d %s", &key, name) != EOF) { /* リストにデータを登録 */ head = add_list(key, name, head); } /* リストの表示 */ show_list(head); /* リストの開放 */ free_list(head); return 0; } /*** リストにデータを登録 ***/ struct list *add_list(int key, char *name, struct list *head) { struct list *p; /* 記憶領域の確保 */ if ((p = (struct list *) malloc(sizeof(struct list))) == NULL) { printf("malloc error\n"); exit(EXIT_FAILURE); } /* リストにデータを登録 */ p->key = key; strcpy(p->name, name); /* ポインタのつなぎ換え */ p->next = head; /* 今までの先頭ポインタを次ポインタに */ head = p; /* 新たな領域を先頭ポインタに */ return head; } /*** リストの表示 ***/ void show_list(struct list *p) { while (p != NULL) { /* 次ポインタがNULLまで処理 */ printf("%3d %s\n", p->key, p->name); p = p->next; } } /*** リストの開放 ***/ void free_list(struct list *p) { struct list *p2; while (p != NULL) { /* 次ポインタがNULLまで処理 */ p2 = p->next; free(p); p = p2; } } これを実行すると、 新しく入力された順にリストが表示されます。 そうではなく、キーの昇順に表示したいです。 どなたかそのように実行できるようにプログラムを書き換えてくれませんか? 図々しいですがよろしくお願いいたします。m(_ _)m

  • C言語解読

    #include <stdio.h> #include <stdlib.h> #include <string.h> #define dBufferSize (32768) #define dPrintFmt "#d: %s\n" typedef struct _NODE NODE; struct _NODE { char *line; NODE *next; }; int RemoveReturnCode(char *string); NODE *MakeNode(char *string); int FreeNodeList(NODE *node); void FreeNode(NODE *node); int PrintNoceList(NODE *node); NODE *ReverseNodeList(NODE **head); int main(void){ char buffer[dBufferSize]; NODE *head = NULL; while (fgets(buffer, dBufferSize, stdin) != NULL){ NODE *pivot; RemoveReturnCode(buffer); pivot = MakeNode(buffer); if (pivot == NULL) return FreeNodeList(head); pivot->next = head; head =pivot; } PrintNodeList(head); ReverseNodelist(&head); PrintNodeList(head); FreeNodeList(head); return 0; } int RemoveReturnCode(char *str){ char *p; if (str == NULL) return -1; for (p = str; *p != '\n' && *p != '\r' && *p != '\0'; p++) ; *p = '\0'; return p - str; } NODE *MakeNode(char *str){ NODE *node; if(str == NULL)return NULL; node = (NODE *)calloc(1,sizeof(NODE)); if(node != NULL){ char *p = (char *)calloc(strlen(str)+1, sizeof(char)); if (p != NULL){ node->line = strcpy(p, str); node->next = NULL; } else{ free(node); node = NULL; } } return node; } int FreeNodeList(NODE *node){ int ct = 0; while (node != NULL){ NODE *next = node->next; FreeNode(node); ct++; node = next; } return ct; } void FreeNode(NODE *node){ free(node->line); free(node); } int PrintNodeList(NODE *node){ int ct; for (ct = 0; node != NULL; node = node->next, ct++) printf(dPrintFmt, ct+1, node->line); return ct; } NODE *ReverseNodeList(NODE **head){ NODE *reverse = NULL; NODE *node = *head; while (node != NULL){ NODE *next = node->next; node->next = reverse; reverse = node; node = next; } return *head = reverse; } このプログラムは単方向リストを利用して複数行のデータを格納していくものであるという ものらしいのですが、そのようなヒントがあっても、まったく解読できません、 手も足も出ない状態です。 できれば、初心者に近い私にもわかるように、関数ごとの解説をおねがいします!! エラーがでるかもしれないのですが・・・大体の意味にはかわりないと思いますので、宜しくお願いします!!

  • C言語 家系図

    問題 構造体personを以下のように仮定する。 struct person { int age; char name[20]; struct person *father; struct person *mother; }; この構造体の表す人の名前、年齢、その人の父親の名前、およびその人の母親の名前を出力する関数 void print_person(struct person *p) を作成せよ。出力の形式は name: 本人の名前 age: 本人の年齢 father: 父親の名前 mother: 母親の名前 となるようにすること。 また、ポインタ father や mother の値が NULL のときには、名前のかわりに unknown と出力するようにせよ。 以上が問題なのですが自分でプログラムを作ってみたところ実行したら、エラーになって矯正終了されてしまいました。 以下が私の作ったプログラムです。 #include <stdio.h> struct person { int age; char name[20]; struct person *father; struct person *mother; }; void set_name(struct person *p, char name[]) { int i; i = 0; while (name[i] != 0) { p->name[i] = name[i]; i++; } p->name[i] = 0; } void print_person(struct person *p) { printf("name:%s", p->name); printf("age:%s\n",p->age); if(p->father != NULL){ printf("father:%s\n",p->father); } else{ printf("unknown"); } if(p->mother != NULL){ printf("mother:%s\n",p->mother); } else{ printf("unknown"); } } int main(void) { struct person me, dad, mom; set_name(&me, "Michael"); me.age = 16; me.father = &dad; me.mother = &mom; set_name(&dad, "David"); dad.age = 38; dad.father = NULL; dad.mother = NULL; set_name(&mom, "Susan"); mom.age = 36; mom.father = NULL; mom.mother = NULL; print_person(&me); print_person(&dad); print_person(&mom); return (0); } どこが違うのか教えていただけないでしょうか?

  • c 言語初心者です。

    c 言語初心者です。 私は下記の構造体配列をつくりました。 しかしバッファオーバーランが起きてエラーが起きてしまいます。 ヒープ領域に問題があるのかもしれませんが、プログラム上どこに原因があるのかが良くわかりません。 どなたかよろしければ教えていただけないでしょうか? #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include<memory.h> struct s { int i; char name[25]; char huri[25]; char num[23]; }; void touroku(struct s *p); void hyouji(struct s *p); int main(void) { struct s data; touroku( &data ); hyouji( &data ); //data.num *= 1; /* dataはポインタではないのでドット演算子 */ hyouji( &data ); return 0; } /* 構造体のメンバを設定する */ void touroku(struct s *p) { int i=0; for(i=1;i<3;i++) { printf( "25文字以内の名前を入力して下さい\n" ); memset(p[i].name, 0, sizeof(p[i].name)); fgets( p[i].name,sizeof(p[i].name) , stdin ); if(strchr(p[i].name,'\n')==NULL)//バッファ処理 { while(getchar() != '\n'); } if(p[i].name[strlen(p[i].name)-1]=='\n')//改行解除 { p[i].name[strlen(p[i].name)-1] = '\0'; } printf("25文字以内のふりがなを入力してください\n"); memset(p[i].huri, 0, sizeof(p[i].huri)); fgets(p[i].huri,sizeof(p[i].huri),stdin); if(strchr(p[i].huri,'\n')==NULL)//バッファ処理 { while(getchar() != '\n'); } if(p[i].huri[strlen(p[i].huri)-1]=='\n')//改行解除 { p[i].huri[strlen(p[i].huri)-1] = '\0'; } printf( "整数を入力して下さい\n" ); memset(p[i].num, 0, sizeof(p[i].num)); fgets(p[i].num,sizeof(p[i].num),stdin ); if(strchr(p[i].num,'\n')==NULL)//バッファ処理 { while(getchar() != '\n'); } if(p[i].num[strlen(p[i].num)-1]=='\n')//改行解除 { p[i].num[strlen(p[i].num)-1] = '\0'; } } } /* 構造体のメンバを出力する */ void hyouji(struct s *p) { int i=0; for(i=1;i<3;i++) printf("%-8s %3s %3s %d\n" ,p[i].name , p[i].huri , p[i].num , i); puts("----------------------------------------------------------------"); return ; }

  • 線形リストのコードでどーしても理解できない個所があります。

    線形リストのコードでどーしても理解できない個所があります。 (以下、コード部分) typedef struct __node { char name[20]; char tel[16]; struct __node *next; } Node; typedef struct { Node *head; Node *tail; } List; Node *AllocNode(void) { return ((Node *)calloc(1, sizeof(Node))); } /*--- 新たに生成したノードを先頭へ挿入 ---*/ void InsertNode(List *list, const char *name, const char *tel) { Node *ptr = list->head; list->head = AllocNode(); strcpy(list->head->name, name); strcpy(list->haed->tel, tel); list->head->next = ptr; } /*--- pが指すノードの直前にノードを挿入 ---*/ void PutNodeP(List *list, Node *p, const char *name, const char *tel) { if (p == list->head) InsertNode(list, name, tel); else { Node *temp = AllocNode(); if (p == list->tail) list->tail = temp; else *temp = *p; strcpy(p->name, name); strcpy(p->tel, tel); temp->next = p; } } 上の29行目以降の≪pが指すノードの直前にノードを挿入≫についてです。 if文部分については理解できますが、else文部分について、何をやっているのかわからないです。Cの基本的な部分(ポインタも含めて)については充分に理解しているつもりです。 どなたか御教授頂けないでしょうか。 長々と書いてしまいましたがよろしくお願いします。

  • 難しい・・・

    待ち行列への挿入と削除をするプログラムです。 先頭のkeyはそれぞれ I…単語を待ち行列に追加 D…単語を待ち行列から削除 P…現在の待ち行列に並んでいる要素を表示 Q…終了 を意味し、 入力例として I lose I eow D dummy P dummy I pop P dummy Q dummy のようなものを入力した時 eow eow pop のように表示されるようにしたいと思っています。 しかしできません>< プログラムは以下の通りです。 #include <stdio.h> #include <string.h> #include <stdlib.h> struct q{ char key; char word; struct q *next; /* 次のデータへのポインタ */ }; struct q *add_q(char key, char *name, struct q *head); void show_q(struct q *p); void free_q(struct q *p); int main(void) { struct q *head; /* 先頭ポインタ */ char word[20]; char key = 0; head = NULL; while(1){ scanf("%c %s",&key,word); switch(key){ case 'I': head=add_q(key, word, head); case 'P': show_q(head); case 'D': free_q(head); case 'Q': exit(1); default: printf("This is unexpected command\n"); }} return 0; } /*** リストにデータを登録 ***/ struct q *add_q(char key, char *word, struct q *head) { struct q *p; /* 記憶領域の確保 */ if ((p = (struct q *) malloc(sizeof(struct q))) == NULL) { printf("malloc error\n"); exit(EXIT_FAILURE); } /* リストにデータを登録 */ p->key = key; strcpy(p->word,word); /* ポインタのつなぎ換え */ p->next = head; /* 今までの先頭ポインタを次ポインタに */ head = p; /* 新たな領域を先頭ポインタに */ return head; } /*** リストの表示 ***/ void show_q(struct q *p) { while (p != NULL) { /* 次ポインタがNULLまで処理 */ printf("%3d %s\n", p->key, p->word); p = p->next; } } /*** リストの開放 ***/ void free_q(struct q *p) { struct q *p2; while (p != NULL) { /* 次ポインタがNULLまで処理 */ p2 = p->next; free(p); p = p2; } }

  • C言語に関する質問

    初めて質問させて頂きます。C言語初心者です。 実は講義で「ファイル中の英文を単語に分けてその出現頻度をカウントするコードを木構造を用いて出力せよ」という課題が出ました。 そこで、参考にするコードを検索しましたところ、以下のURLにあるベストアンサーのコードが近いと感じました。 http://okwave.jp/qa/q4155655.html コードの内容は以下の通りになります。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> typedef struct node Node; struct node{ char *word; int count; Node *left,*right; }; Node *root=NULL; void compose(FILE *fp); void inorder(Node *p); void strlower(char *s); int main(int argc, char *argv[]) { FILE *fp; Node *new; fp=fopen(argv[1],"r"); if(fp==NULL){puts("ファイルを開けません");return(-1);} compose(fp); inorder(root); return (0); } void strlower(char *s){ while(*s!=NULL){*s=tolower(*s);s++;} } void compose(FILE*fp){ Node **p,*new; char buf[256]; while(1){ fscanf(fp,"%[^a-zA-Z0-9]",buf); if(fscanf(fp,"%[a-zA-Z0-9]",buf)==EOF)break; strlower(buf); if(root==NULL){ new=(Node *)malloc(sizeof(Node)); new->left=NULL; new->right=NULL; new->word=strdup(buf); new->count=1; root=new; }else{ *p=root; while(1){ if(strcmp(buf,(*p)->word)==0){ (*p)->count++;break; }else if(strcmp(buf,(*p)->word)<0){ if((*p)->left==NULL){ new=(Node *)malloc(sizeof(Node)); new->left=NULL;new->right=NULL;new->word=strdup(buf);new->count=1; (*p)->left=new; break; }else{ *p=(*p)->left; } }else{ if((*p)->right==NULL){ new=(Node *)malloc(sizeof(Node)); new->left=NULL; new->right=NULL; new->word=strdup(buf); new->count=1; (*p)->right=new; break; }else{ *p=(*p)->right; } } } } } } void inorder(Node*p){ if (p==NULL) return; inorder(p->left); printf("%s %d\n",p->word, p->count); inorder(p->right); } しかし、これをそのままコンパイル・実行すると、コンパイル時に以下の注意が出ます。 warning comparison between pointer and integer ('int' and 'char *') while(*s!=NULL){*s=tolower(*s);s++;} 上記の注意を無視してそのまま実行すると、segmatation faultが出てしまいますorz おそらく、sの型が*s=s[]なので、注意の中の「s++」の部分で誤作動を起こしている(s++を実行するにはsはint型でなければならない)と思うのですが、どうコード文を変えれば良いのかがよくわかりません。 どなたかお教え頂けると幸いです。どうぞよろしくお願いしますm(_ _)m

  • リストの削除について(構造体)

    リストの削除のプログラムを実行して行ってみると、リストの削除処理中にプログラムが終わって変更後処理がうまく表示されません。どこが間違っているかが分からないしだいです。返答のほどよろしくお願いいたします。 #include<stdio.h> #include<malloc.h> #include<string.h> struct list{ char name[20]; int age; struct list *next; }; void main(void) { struct list *head, *p, *n, *old; char key[20]; /*ダミーノード作成*/ head = (struct list*)malloc(sizeof(struct list)); old = head; while(p = (struct list*)malloc(sizeof(struct list)), printf("name age入力\n"), scanf("%s %d", p -> name, &p -> age) != EOF){ old -> next = p; old = p; } free(p); old -> next = NULL; p = head -> next; printf("変更前リスト\n"); while(p != NULL){ printf("name:%s age:%d\n",p -> name, p -> age); p = p -> next; } printf("削除key入力(name)\n"); gets(key); n = head; while(n != NULL){ old = n; n = n -> next; //printf("n -> name %s\n", n -> name); if(strcmp(n -> name, key) == 0){ printf("%s削除\n", key); //printf("n -> name %s old -> name %s\n", n -> name, old -> name); old -> next = n -> next; } } p = head -> next; printf("変更後リスト\n"); while(p != NULL){ printf("name:%s age:%d\n", p -> name, p -> age); p = p -> next; } }

  • C言語について教えてください。

    #include <ctype.h> #include <stdio.h> void name_toupper(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = toupper(istr[i]); i++; } ostr[i] = '\0'; } void name_tolower(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { ostr[i] = tolower(istr[i]); i++; } ostr[i] = '\0'; } void name_change(char istr[], char ostr[]) { unsigned i = 0; while (istr[i]) { if(isupper(istr[i])) { ostr[i] = tolower(istr[i]); } else { ostr[i] = toupper(istr[i]); } i++; } ostr[i] = '\0'; } int main(void) { char buffer[100]; char result[100]; printf("文字"); gets(buffer); name_toupper(buffer,result); printf("大文字: %s\n", result); name_tolower(buffer,result); printf("小文字: %s\n", result); name_change(buffer,result); printf("大小交換: %s\n", result); return 0; } 出力結果 文字abc DEFG 大文字: ABC DEFG 小文字: abc defg 大小交換: ABC defg 上のプログラムで文字関数isupperを用いずにプログラムする方法を教えてもらえませんか? もしくわ、用いずにプログラムすることは不可能ですか? 教えてください。 よろしくお願いします。