Get Next Nodeコメント3を挿入します.自己問答


このドキュメントには、私の挿入操作とプロジェクトを開く手順が記録されています.符号化とドキュメントの並列作成では、不適切な知識が多いため、正解の参考には向いていないことに注意してください.
時間があれば、カール・ニューポートが書いたベストセラー「深い仕事」を読むことをお勧めします.
プロジェクトはある程度進んだ.中間検査の感覚として、コードを書くときの悩みと私の解決方法を書きたいと思います.

静的変数が必要なのはなぜですか?


バッファのサイズを4とします.文字列「abcdnefg」からn文字を抽出するには、read関数を2回呼び出す必要があります.2回の呼び出しの場合、nに読み込めますが、問題が発生します.
バッファのサイズは、ファイルからインポートする文字数です.以上の場合は4で、ファイルから4文字の値を抽出します.すなわち、nは、後のefgの3文字を読み出す.ユーザーがgnlを再度呼び出す場合、jefgを無視してabcdnを返すのはなぜですか?readが2回呼び出されたため、ファイル内のすべての文字が読み込まれたため、これらの文字は読み込めません.したがって、現在の読み出しバッファの値を予め格納するために一時バッファが必要である.gnl関数が複数回呼び出されても、一時バッファは、以前に呼び出された値を保存する必要があります.このようにしてこそ、上記の場合にefgを持つことができる.一度だけ初期化された静的変数は,我々が望む一時バッファの条件を完全に満たす.

静的変数のタイプは何ですか?


いくつかの悩みと失敗のため、バッファが備えるべき条件を考えることができます.

1.深さダック定数配列


これは私が初めて考えた非常に無知な方法です.バッファのサイズがどれくらいあるか分かりませんが、まず
これは大順位を発表してから見る方法です.多くの問題(バッファの値が1か、深さの大きい配列よりも大きな深さのバッファ)があるためです.
すなわち、バッファの長さは可変でなければならない.

2.動的配置


これは私の2回目の考え方です.read関数の正しい結果値は、読み取りバッファ内の文字列の数を返します.すなわち、一時バッファを動的に割り当て、バッファの値を保存する.この方法の問題は、バッファの値を再読み込みするたびに、一時バッファを解放し、寸法を再割り当てすることである.例を挙げましょう1~10000の間にnがなければ、連続したファイルがあるとします.このときバッファのサイズが1の場合、対応する方法はこの論理である.
1.read関数で値を読み込みます.1読みました
2.読み出した値を保存するための一時バッファサイズを1として動的に割り当てる
3.nまたはeofは会っておらず、readで2を再度読み込みます.
4.一時バッファのサイズが1であるため、サイズを2に再割り当てして読み出します.
このようにバッファサイズを割り当て、再割り当てする様子はあまりよく見えません.しかし、一度の配分が大きいと、1つ目の場合の問題にも直面します.もう1つの問題は,一時バッファの格納後処理が面倒であることである.
バッファのサイズを100とする文字列「abcdnefghnijk」があります.gnl呼び出しの場合、read関数呼び出しは文字列全体を一時バッファに格納します.gnlを初めて実行したときは「abcd」
2回目の実行時には「efgh」を出力し、3回目の実行時には「ijk」を出力しなければならないが、一時バッファで「どこからどこへ出力するか」を決定するのは面倒なことだ.int型静的変数を用いたインデックス管理は加点を受けず,1行の読み出し値を除いて,再割り当ての方式は当初想定した問題とあまり変わらない.
すなわち、ストレージと次の呼び出しの処理は簡単であるべきである.
こう考えるのが次の解決策です.

3.活用カタログ。


リストは長さが可変であるだけでなく、各文字がノードであるため、文字を切り取る処理も簡単です.
次に、リストを使用する概略コードロジックを示します.
int		get_next_line(int fd, char **line)
{	
	static t_list		*g_buffer = 0;
	char			buffer[BUFFER_SIZE];
	int 			ret;

	while(1)
	{
		if ((ret = read(fd,buffer,BUFFER_SIZE)) <= 0)
		{
			//버퍼에 남은 문자열이 있을 때
			if(gnl_lst_size(g_buffer) > 0)
			{
            			//매개변수의 1일 경우, 노드의 헤드에서부터 \n까지 잘라냄.
				*line = gnl_strdup(g_buffer,'\n',gnl_lst_find(g_buffer,'\n'));
				
				gnl_clear(&g_buffer,1);
				return (1);
			}
            		//매개변수가 0일 경우 그냥 리스트 클리어 함수
			gnl_clear(&g_buffer,0);
			return (0);
		}
        	//임시 버퍼에 버퍼에 담긴 값을 저장함.
		gnl_backup(&g_buffer,buffer,ret);
		if (gnl_lst_find(g_buffer,'\n') != -1)
		{
        		//임시 버퍼에 담긴 값을 *line에 복사하여 넘겨준다(\n전까지만)
			*line = gnl_strdup(g_buffer,'\n',gnl_lst_find(g_buffer,'\n'));
			gnl_clear(&g_buffer,1);
			return (1);
		}
	}
}
リストが長いほど、ノードを追加する時間が長くなります.
計画はリングリストに変更された.
大体のコードはそうですが、まだ長い道のりがあります.もっと良い方法があるかどうか考えなければなりません.
例外処理も行い,他のfdが入った場合も考慮し,normも処理する.
でも今日はこんなに進歩して満足しているはずです.
最後に、フランク・シナトラのmyway歌詞を印刷しました.
歌と一緒に聴いてほしい.
Frank Sinatra - My Way