いつもお世話になっております。
ファイルの内容をコピーするプログラムを作成しています。
しかし、現在、コピー先のファイルに余計な改行が1つ追加されて出力されてしまっています。
疑問点①(terminal上に記載)
変数tmpLineに入っているのが、
\n000d\n→\nCRLFなのは、分かりますが、
どうして、急にCRLFが変数の中に入ってきたのかが分かりません。
というのも、これまでは、普通に、変数に入っていたのは、\n(例えば、"dddd\n")であったからです。
さらに、\nCRLFが入ってしまっているということは、2行分改行されてしまうと思います。(\nで1行分改行されて、CRLFで1行分改行される)
しかし、そんなプログラムは組んでいないと思っているので、原理が分かりません。
疑問点②(terminal上に記載)
おそらく、2回ループが回って、\nCRLFが読み込まれて、ファイルに記述されてしまっているので、
それが原因だとは思うのですが、どうして、もう一度、同じ\nCRLFが読み込まれ、記述されてしまっているのかが分かりません。
ご教授いただけませんでしょうか。
よろしくお願いいたします。
●環境
macOS Big Sur
Ver.11.1
C
1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5#define ARGUMENT_NUM 3 6#define SIZE 254 7 8int main(int argc, char **argv) 9{ 10 FILE *fromFp = NULL; 11 FILE *toFp = NULL; 12 char fromFile[SIZE]; // コピー元ファイル 13 char toFile[SIZE]; // コピー先ファイル 14 char tmpLine[SIZE]; // 読み取った文字列を格納するための変数 15 int iRet = 0; 16 char *cptr = NULL; 17 18 memset(fromFile, 0x00, sizeof(fromFile)); 19 memset(toFile, 0x00, sizeof(toFile)); 20 memset(tmpLine, 0x00, sizeof(tmpLine)); 21 22 if (argc != ARGUMENT_NUM){ 23 printf("コマンドライン引数エラー\n"); 24 return -1; 25 } 26 memcpy(fromFile, argv[1], sizeof(fromFile)); 27 memcpy(toFile, argv[2], sizeof(toFile)); 28 29 fromFp = fopen(fromFile, "r"); 30 if (fromFp == NULL){ 31 printf("fopen失敗!\n"); 32 return -1; 33 } 34 35 toFp = fopen(toFile, "w"); 36 if (toFp == NULL){ 37 printf("fopen失敗!\n"); 38 return -1; 39 } 40 41 while(!feof(fromFp)){ 42 cptr = fgets(tmpLine, sizeof(tmpLine) / sizeof(char), fromFp); 43 if (!cptr && !feof(fromFp)){ 44 printf("読み込みエラー\n"); 45 goto FILE_CLOSE; 46 } 47 iRet = fputs(tmpLine, toFp); 48 if (iRet == EOF){ 49 printf("書き込み失敗\n"); 50 goto FILE_CLOSE; 51 } 52 53 } 54 55 FILE_CLOSE: 56 iRet = fclose(fromFp); 57 if (iRet != 0){ 58 printf("fclose失敗【読み取り元ファイル】"); 59 return -1; 60 } 61 iRet = fclose(toFp); 62 if (iRet != 0){ 63 printf("fclose失敗【読み取り元ファイル】"); 64 return -1; 65 } 66 67 68}
terminal
1ユーザー名@コンピュータ名 第2回 % ls 2a.out test.txt 問題10.txt 問題8 3a.out.dSYM test2.txt 問題5.c 問題8.c 4base.h test3.txt 問題6 問題9.c 5dump.txt 問題10.c 問題7 書き込み用ファイル.txt 6ユーザー名@コンピュータ名 第2回 % cat test.txt 7aaa 8bbb 9ccc 10ddd 11 12ユーザー名@コンピュータ名 第2回 % ./a.out test.txt test3.txt 13ユーザー名@コンピュータ名 第2回 % cat test3.txt 14aaa 15bbb 16ccc 17ddd 18 19 // 改行が1つ多くコピーされてしまっている。 20ユーザ名@コンピュータ名 第2回 % 21
gdb(terminal)
1Thread 2 hit Breakpoint 2, main (argc=3, argv=0x7ffeefbff6f8) at 問題8.c:37 237 while(!feof(fromFp)){ 3(gdb) n 438 cptr = fgets(tmpLine, sizeof(tmpLine) / sizeof(char), fromFp); 5(gdb) n 639 if (!cptr && !feof(fromFp)){ 7(gdb) print tmpLine 8$1 = "aaa\n", '\000' <repeats 249 times> 9(gdb) n 1043 iRet = fputs(tmpLine, toFp); 11(gdb) n 1244 if (iRet == EOF){ 13(gdb) print tmpLine 14$2 = "aaa\n", '\000' <repeats 249 times> 15(gdb) print iRet 16$3 = 4 17(gdb) n 1837 while(!feof(fromFp)){ 19(gdb) n 2038 cptr = fgets(tmpLine, sizeof(tmpLine) / sizeof(char), fromFp); 21(gdb) n 2239 if (!cptr && !feof(fromFp)){ 23(gdb) print tmpLine 24$4 = "bbb\n", '\000' <repeats 249 times> 25(gdb) n 2643 iRet = fputs(tmpLine, toFp); 27(gdb) n 2844 if (iRet == EOF){ 29(gdb) print tmpLine 30$5 = "bbb\n", '\000' <repeats 249 times> 31(gdb) n 3237 while(!feof(fromFp)){ 33(gdb) n 3438 cptr = fgets(tmpLine, sizeof(tmpLine) / sizeof(char), fromFp); 35(gdb) n 3639 if (!cptr && !feof(fromFp)){ 37(gdb) print tmpLine 38$6 = "ccc\n", '\000' <repeats 249 times> 39(gdb) n 4043 iRet = fputs(tmpLine, toFp); 41(gdb) n 4244 if (iRet == EOF){ 43(gdb) print tmpLine 44$7 = "ccc\n", '\000' <repeats 249 times> 45(gdb) n 4637 while(!feof(fromFp)){ 47(gdb) n 4838 cptr = fgets(tmpLine, sizeof(tmpLine) / sizeof(char), fromFp); 49(gdb) n 5039 if (!cptr && !feof(fromFp)){ 51(gdb) print tmpLine 52$8 = "ddd\n", '\000' <repeats 249 times> 53(gdb) n 5443 iRet = fputs(tmpLine, toFp); 55(gdb) n 5644 if (iRet == EOF){ 57(gdb) print tmpLine 58$9 = "ddd\n", '\000' <repeats 249 times> 59(gdb) n 6037 while(!feof(fromFp)){ 61(gdb) n 6238 cptr = fgets(tmpLine, sizeof(tmpLine) / sizeof(char), fromFp); 63(gdb) n 6439 if (!cptr && !feof(fromFp)){ 65(gdb) print tmpLine 66$10 = "\n\000d\n", '\000' <repeats 249 times> // \n\000d\n \nCRLF(疑問点①) 67(gdb) n 6843 iRet = fputs(tmpLine, toFp); 69(gdb) n 7044 if (iRet == EOF){ 71-----------------------疑問点②------------------------------------------------- 72(gdb) print tmpLine 73$11 = "\n\000d\n", '\000' <repeats 249 times> // 一旦、\n\000d\n (\nCRLF)がterminal上に出力される。 74(gdb) n 7537 while(!feof(fromFp)){ 76(gdb) n 7738 cptr = fgets(tmpLine, sizeof(tmpLine) / sizeof(char), fromFp); 78(gdb) n 7939 if (!cptr && !feof(fromFp)){ 80(gdb) print tmpLine 81$12 = "\n\000d\n", '\000' <repeats 249 times> // もう一度、\n\000d\n (\nCRLF)が読み込まれて 82(gdb) n 8343 iRet = fputs(tmpLine, toFp); // 再度、\n\000d\n \nCRLFが出力されてしまっている。(→余計な改行が1行多く表示されてしまっている原因?) 84(gdb) n 8544 if (iRet == EOF){ 86(gdb) print tmpLine 87$13 = "\n\000d\n", '\000' <repeats 249 times> 88--------------------------------------------------------------------------------- 89(gdb) n 9037 while(!feof(fromFp)){ 91(gdb) n 9252 iRet = fclose(fromFp); 93(gdb) n 9453 if (iRet != 0){ 95(gdb) n 9657 iRet = fclose(toFp); 97(gdb) n 9858 if (iRet != 0){ 99(gdb) n 10064 } 101(gdb) 102
回答3件
あなたの回答
tips
プレビュー