みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

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;
}



このプログラムは単方向リストを利用して複数行のデータを格納していくものであるという
ものらしいのですが、そのようなヒントがあっても、まったく解読できません、
手も足も出ない状態です。

できれば、初心者に近い私にもわかるように、関数ごとの解説をおねがいします!!

エラーがでるかもしれないのですが・・・大体の意味にはかわりないと思いますので、宜しくお願いします!!

投稿日時 - 2008-01-07 01:36:09

QNo.3656859

32i

すぐに回答ほしいです

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

コメントで解説を加えておきました。
基本的なアルゴリズムですので、構造は難しくないと思います。
一度ご自分でリストを作成するプログラムを記述することをお勧めします。

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

#define dBufferSize (32768) // 1行分の文字列を保持するためのバッファのサイズ
#define dPrintFmt "%d: %s\n" // 文字列を表示する際の書式

// 連結リストを実現するための構造体
// NODE構造体をつなげてリストを作成する
typedef struct _NODE NODE;
struct _NODE {
char *line; // 文字列へのポインタ
NODE *next; // 次のNODEへのポインタ
};

int RemoveReturnCode(char *string);
NODE *MakeNode(char *string);
int FreeNodeList(NODE *node);
void FreeNode(NODE *node);
int PrintNodeList(NODE *node);
NODE *ReverseNodeList(NODE **head);

int main(void){
char buffer[dBufferSize]; // 1行分の文字列を保持するバッファ
NODE *head = NULL;

// 標準入力から1行毎に文字列を読み取り、連結リストに格納
while (fgets(buffer, dBufferSize, stdin) != NULL){
NODE *pivot;

RemoveReturnCode(buffer); // 文字列末尾の改行コードを削除
pivot = MakeNode(buffer); // 新規NODE作成
if (pivot == NULL) return FreeNodeList(head); // NODE作成に失敗した場合は、リストを削除して終了
// 作成したNODEをリスト先頭に挿入
pivot->next = head;
head = pivot;
}
PrintNodeList(head); // リストを表示
ReverseNodeList(&head); // リストを逆転
PrintNodeList(head); // リストを表示
FreeNodeList(head); // リストを削除

return 0;
}

/*
文字列末尾の改行コードを削除
@param str 文字列
@return 文字列長
*/
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作成
@param str 文字列
@return 作成したNODE(作成失敗の場合NULL)
*/
NODE *MakeNode(char *str){
NODE *node = NULL;

if(str == NULL)return NULL;

node = (NODE *)calloc(1,sizeof(NODE));
if(node != NULL)
{
// node領域確保成功
char *p = (char *)calloc(strlen(str)+1, sizeof(char)); // 文字列を保持する領域を確保
if (p != NULL)
{
// p領域確保成功
node->line = strcpy(p, str); // 文字列をコピー
node->next = NULL;
}
else
{
// p領域確保失敗
free(node);
node = NULL;
}
}
else
{
// node領域確保失敗
node = NULL;
}
return node;
}

/*
連結リストを削除
@param node 先頭のNODE
@return 削除したNODEの数
*/
int FreeNodeList(NODE *node){
int ct = 0;

while (node != NULL){
NODE *next = node->next;
FreeNode(node);
ct++;
node = next;
}

return ct;
}

/*
単一のNODEを削除
@param node 削除するNODE
*/
void FreeNode(NODE *node){
free(node->line);
free(node);
}

/*
連結リストが保持する文字列を1行毎に表示
@param node 先頭のNODE
@return 表示した行数
*/
int PrintNodeList(NODE *node){
int ct;

for (ct = 0; node != NULL; node = node->next, ct++)
printf(dPrintFmt, ct+1, node->line);

return ct;
}

/*
連結リストを逆転
@param head 先頭のNODEへのダブルポインタ
*/
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;
}

投稿日時 - 2008-01-07 10:12:45

お礼

お礼遅くなってごめんなさい。
C言語にCASL、とプログラミングに翻弄された
日々がいったん落ち着くまで時間がかかりました。

そういってる間に試験が近づいています。。
また、回答者様にはくだらない問題かもしれませんが、
気が向けば、手助けをお願いいたします。

ありがとうございました。

投稿日時 - 2008-01-12 20:58:57

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.1

 
 向こうの人に失礼なことはやめましょう。

 初心者なら、解るようになるまで勉強しましょう。
いきなり二階へ飛び上がるのは無理です。
ちゃんと階段を一段づつ上がりましょう。
 

 

投稿日時 - 2008-01-07 08:43:21