登録される順番が・・・

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ME

登録される順番が・・・

#1

投稿記事 by ME » 17年前

ファイルに1行ずつデータを書き出して
1 名前1
2 名前2
という風に後に追加することはできるようになったのですが、
そのファイルを読み出して、
キーボード入力でデータを追加すると
4 名前4
3 名前3
1 名前1
2 名前2
という風に前にデータが追加されてしまいます。

tail = add( str, num, tail);
で読み出したファイルのデータの登録に使っている関数は↓
List *add( char *str, int num, List *tail )
{
List *p;

if ((p = (List *) malloc(sizeof(List))) == NULL) {
printf("malloc error\n");
exit(1);
}

strcpy(p->name, str);
p->num = num;

p->next = NULL;
if (tail != NULL) tail->next = p;

return p;
}

同じ関数が使えなかったので、キーボードから入力するデータは↓で登録しています。
head = add_sort( name, num, head );
struct list *add_sort( char *str,int num, struct list *head )
{
struct list *p;

/* 新規リストにデータを登録 */
if ( ( p = ( struct list * )malloc( sizeof( struct list ) ) ) == NULL ) {
printf( "malloc error\n" );
exit( 1 );
}
strcpy( p->name, str );
p->num = num;

if ( head == NULL || num > head->num ) {
p->next = head;
return p;
}

return head;
}

head(先頭)指定をtail(末尾)に変更しても、上手くいきません。
初歩的な質問かもしれませんが、どこを変更したらいいか教えてください。m(_ _)m

box

Re:登録される順番が・・・

#2

投稿記事 by box » 17年前

main関数などを含めて、今のソースコードを全部見せてください。
貼り付ける際、インデントを有効にするために
コードの前後を<pre>タグと</pre>タグではさんでください。

ME

Re:登録される順番が・・・

#3

投稿記事 by ME » 17年前

ソースコードを貼り付けました。これで大丈夫でしょうか?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "head.h"


List *write(int code, List *head, List *tail)
{
	List *p;
	char name[30];
	int num=1;

	if (head != NULL){
		for ( p = head;  p->next != NULL; p = p->next )	num++;
		num++;
	}
	code = 1;
	while(code==1){
	if(code == 4) break;
		printf( "名前:" );   scanf( "%s", name );getchar();
		printf("No.%d\n",num);
		printf("%s,No.%d\n",name, num);
		head = add_sort( name, num, head );
        if( head == NULL ) head = tail;
		num++;
		printf("追記:1 終了:4 →",);
		while(1){
			scanf("%d",&code);getchar();
			if (code==1 || code==4 ) break;
			}else{ fflush(stdin);
			}
		}
	}
	return(head);
}
List *read( List *head, List *tail )
{
	FILE *fw;
	char fname[21], line[100];
	char str[30];
	int  num;
	head = NULL;
	tail = NULL;

	printf( "ファイル名:" );	scanf("%s",fname);getchar();

	while( ( fw=fopen( fname, "r" ) ) == NULL) {
		printf( "ファイルがありません。\nファイル:" );
		scanf("%s",fname);
	}
	
    while( fgets( line, 100, fw ) != NULL ) {
	line[strlen(line)-1] = '\0';
	sscanf(line, "%s,No.%d", str, &num);
	tail = add( str,num,tail);
         if( head == NULL ) head = tail;
	}
	fclose( fw );
	return(head);
}

void dispall( List *p )
{
	int code;
	while ( p != NULL) {
		printf( "%s,No.%d\n",p->name,p->num );
			p = p->next;
			}
}


int main( void )
{
        List *head= NULL;
        List *tail= NULL;
        List *p2;
        int code;

        while( 1 ) {
	printf( "入力:1 読込:2 表示:3 終了:4\n");
	scanf( "%d", &code );getchar();
         if ( code == 4 )    break;
         else if ( code == 1 ){ head = write(code, head, tail);
         }else if ( code == 2 ){ head = read(head,tail);
         }else if ( code == 3 ){ dispall(head);
         }else{fflush(stdin);
	}
        }
       while ( p != NULL ) {
                p2 = p->next;
                free( p );
                p = p2;
        }
        return 0;
}

box

Re:登録される順番が・・・

#4

投稿記事 by box » 17年前

> ソースコードを貼り付けました。

head.h もお願いします。

ME

Re:登録される順番が・・・

#5

投稿記事 by ME » 17年前

たびたびすみません・・・
#define  BUF 128

typedef struct list {
         char name[30];
	int num;
	struct list *next;      /* 次のデータへのポインタ */
	struct list *prev;      /* 次のデータへのポインタ */
}List;
です。

box

Re:登録される順番が・・・

#6

投稿記事 by box » 17年前

貼り付けられたソースコードをそのまま私のところで
コピー&ペーストしてBorland C++ Compilerでコンパイルしました。
すると、下記のエラーが出ました。
さしあたり、これらのエラーや警告をなくしていただけますか?
警告 W8065 D:\My Programs\C\temp1\temp1.c 23: プロトタイプ宣言のない関数 'add_sort' の呼び出し(関数 write )
警告 W8069 D:\My Programs\C\temp1\temp1.c 23: 移植性のないポインタ変換(関数 write )
エラー E2188 D:\My Programs\C\temp1\temp1.c 26: 式の構文エラー(関数 write )
エラー E2054 D:\My Programs\C\temp1\temp1.c 30: else の位置が誤っている(関数 write )
警告 W8070 D:\My Programs\C\temp1\temp1.c 33: 関数は値を返すべき(関数 write )
エラー E2040 D:\My Programs\C\temp1\temp1.c 34: 宣言が正しく終了していない
エラー E2190 D:\My Programs\C\temp1\temp1.c 35: 不要な }
警告 W8065 D:\My Programs\C\temp1\temp1.c 55: プロトタイプ宣言のない関数 'add' の呼び出し(関数 read )
警告 W8069 D:\My Programs\C\temp1\temp1.c 55: 移植性のないポインタ変換(関数 read )
警告 W8080 D:\My Programs\C\temp1\temp1.c 69: 宣言された 'code' は使われていない(関数 dispall )
エラー E2451 D:\My Programs\C\temp1\temp1.c 89: 未定義のシンボル p(関数 main )
警告 W8080 D:\My Programs\C\temp1\temp1.c 95: 宣言された 'p2' は使われていない(関数 main )
*** 5 errors in Compile ***

Justy

Re:登録される順番が・・・

#7

投稿記事 by Justy » 17年前

 動かないからテストしていませんが、add_sort()の "p->num = num"以下を
[color=#d0d0ff" face="monospace]    p->num = num; 
    p->next = NULL; 
    
    if(head)
    {
        struct list *q = head; 
        while(q->next)
            q = q->next;
        q->next = p;
    }
    else
    {
        p->next = NULL;
        head = p;
    }
    return head; [/color]
 な感じにすれば、それっぽい動きになるかなぁ、と。

 あと
[color=#d0d0ff" face="monospace]fflush(stdin);[/color]
 は動作を保証されていません。
[color=#d0d0ff" face="monospace]rewind(stdin);[/color]
 としてください。

ME

Re:登録される順番が・・・

#8

投稿記事 by ME » 17年前

boxさんJustyさんありがとうございます。
boxさん指摘のエラーを全部訂正して、
Justyさんの助言通りにプログラムを変更したら、
データが後ろに追加されるプログラムにすることができました。
ありがとうございました!!

一応出来上がったソースを載せておきます。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define  BUF 128

typedef struct list {
    char name[30];
	int num;
	struct list *next;      /* 次のデータへのポインタ */
	struct list *prev;      /* 次のデータへのポインタ */
}List;

List *add( char *str, int num, List *tail ) 
{ 
	List *p; 

	if ((p = (List *) malloc(sizeof(List))) == NULL) { 
		printf("malloc error\n"); 
		exit(1); 
		} 

	strcpy(p->name, str); 
	p->num = num; 

	p->next = NULL; 
	if (tail != NULL) tail->next = p; 

	return p; 
} 

List *add_sort( char *str,int num, List *head ) 
{ 
	List *p; 

	/* 新規リストにデータを登録 */ 
	if ( ( p = ( List * )malloc( sizeof( List ) ) ) == NULL ) { 
		printf( "malloc error\n" ); 
		exit( 1 ); 
		} 
	strcpy( p->name, str ); 
	p->num = num; 
    p->next = NULL; 
    
    if(head){
        List *q = head; 
        while(q->next)
            q = q->next;
        q->next = p;
    }else{
        p->next = NULL;
        head = p;
    }
    return head; 

} 

List *write(int code, List *head, List *tail)
{
	List *p;
	char name[30];
	int num=1;

	if (head != NULL){
		for ( p = head;  p->next != NULL; p = p->next )	num++;
		num++;
		}
	code = 1;
	while(code==1){
	if(code == 4) break;
		printf( "名前:" );   scanf( "%s", name );getchar();
		printf("No.%d\n",num);
		printf("%s	No.%d\n",name, num);
		head = add_sort( name, num, head );
        if( head == NULL ) head = tail;
		num++;
		printf("追記:1 終了:4 →");
		while(1){
			scanf("%d",&code);getchar();
			if (code==1 || code==4 ) break;
			else fflush(stdin);
		}
	}
	return(head);
}
List *read( List *head, List *tail )
{
	FILE *fw;
	char fname[21], line[100];
	char str[30];
	int  num;
	head = NULL;
	tail = NULL;

	printf( "ファイル名:" );	scanf("%s",fname);getchar();

	while( ( fw=fopen( fname, "r" ) ) == NULL) {
		printf( "ファイルがありません。\nファイル:" );
		scanf("%s",fname);
	}
	
    while( fgets( line, 100, fw ) != NULL ) {
	line[strlen(line)-1] = '\0';
	sscanf(line, "%s	No.%d", str, &num);
	tail = add( str,num,tail);
         if( head == NULL ) head = tail;
	}
	fclose( fw );
	return(head);
}

void dispall( List *p )
{
	while ( p != NULL) {
		printf( "%s	No.%d\n",p->name,p->num );
			p = p->next;
			}
}


int main( void )
{
   List *head= NULL;
   List *tail= NULL;
   List *p;
   int code;

   while( 1 ) {
		printf( "入力:1 読込:2 表示:3 終了:4 →");
		scanf( "%d", &code );getchar();
		if ( code == 4 )    break;
        else if ( code == 1 ){ head = write(code, head, tail);
       }else if ( code == 2 ){ head = read(head,tail);
       }else if ( code == 3 ){ dispall(head);
       }else rewind(stdin);
   }
	while ( head != NULL ) {
        p = head->next;
        free( head );
        head = p;
    }
        return 0;
}

閉鎖

“C言語何でも質問掲示板” へ戻る