目錄git
目錄數組
執行 od -tx -tc 1.txt
的命令顯示以下:函數
[yogile@yogile-pc MyOD]$ od -tx -tc 1.txt 0000000 0a333231 0a333231 34340a0a 0a343434 1 2 3 \n 1 2 3 \n \n \n 4 4 4 4 4 \n 0000020 32330a0a 34323334 32330a32 34323334 \n \n 3 2 4 3 2 4 2 \n 3 2 4 3 2 4 0000040 0000000a \n 0000041
(1) main.c 實現文件讀取操做,經過循環輸出每16字符第一個字符所佔的字節序號,積極在循環中調用輸出顯示函數,最後顯示最後一字符的字節序號。學習
(2) tans_0x.c 實現函數 void tans_0x(char char_pl[], int i);
實現對每16字符組輸出顯示,以每四個字節爲一組,依次輸出四次,並按照小端法形式輸出顯示。測試
(3) tans_pr.c 實現函數 void tans_pr(char char_pl[], int i);
按序輸出該16字符組,與 tans_0x();
函數輸出對齊。編碼
// 頭文件 int main(/* 命令行參數 */) { if (/* 打開文件失敗條件*/) { // 結束程序 } while(/* 條件 */) { // 調用tans_0x(); // 調用tans_pr(); } if (/* 判斷文件有字符 */) { // 輸出最後一字符的字節序號 } else { // 輸出 "0000000" } return 0; } void tans_0x(char char_pl[], int i_n) { // for循環,將16字符組以每四個字節爲一組,按照小端法形式排序 if (/* 4字符組爲"00000000"時 */) { // 不輸出 } else { // 輸出 } } void tans_0x(char char_pl[], int i_n) { for (/* i從0到i_n-1*/) { if (char_pl[i] == '\n') { printf(" \\n"); } else { // 輸出字符 } } }
# include# include # include "tansp.h" int main(int argc, char *argv[]) { // 調用命令行參數args[0],實現文件的選擇 FILE *fp=NULL; if ( (fp = fopen(argv[1], "r")) == NULL) { printf("您輸入的文件有誤,請從新輸入。\n"); exit(0); } char ch; char char_perline[16]; int i=0,j=0,k=0; int flag_change=0; while( (ch = fgetc(fp)) != EOF ) { if (i % 16 == 0) { printf("%07o",16*j); j++; } if (i == 16) { i=0; for (k=0; k<16; k++) { char_perline[k] = '\0'; } } if (i < 16) { char_perline[i] = ch; if (i == 15) { tans_0x(char_perline, 16); tans_pr(char_perline, 16); printf("\n"); } } i++; flag_change++; } if (flag_change != 0) { if (i < 16) { tans_0x(char_perline, i); tans_pr(char_perline, i); printf("\n"); } printf("%07o\n",16*(j-1)+i); } else { printf("0000000\n"); } fclose(fp); return 0; }
# include# include # include "tansp.h" void tans_0x(char char_pl[], int i_n) { int i,j; int i_t=0; int left_n = i_n % 4; int have_n = i_n / 4; char char_temp[16] = {0}; for (i=i_n; i<16; i++) { char_pl[i] = '\0'; } for (int i=0; i<4; i++) { char_temp[4*i+3] = char_pl[4*i+0]; char_temp[4*i+2] = char_pl[4*i+1]; char_temp[4*i+1] = char_pl[4*i+2]; char_temp[4*i+0] = char_pl[4*i+3]; } for (i=0; i<8; i++) { printf(" "); } for (i=0; i<4; i++) { if (i != 0) { printf(" "); } if (char_temp[4*i] == '\0') { if (char_temp[4*i+1] == '\0') { if (char_temp[4*i+2] == '\0') { if (char_temp[4*i+3] == '\0') { // 不輸出 break; } } } } for (j=0; j<4; j++) { printf("%.2x", char_temp[4*i+j]); } } printf("\n"); }
# include# include # include "tansp.h" void tans_pr(char char_pl[], int i_n) { int i_t=0; printf(" "); for (i_t=0; i_t < i_n; i_t++) { if (char_pl[i_t] == '\n') { printf(" \\n"); } else if (char_pl[i_t] == '\0') { break; } else { printf(" %c", char_pl[i_t]); } } }
#ifndef TANSP_H #define TANSP_H void tans_pr(); void tans_0x(); #endif
Makefile
.net
# This is a make file. # Generate using static library. myod:bin/myod ln -s bin/myod myod bin/myod:src/main.c libs/libtansp.a gcc src/main.c libs/libtansp.a -I include/ -o bin/myod libs/libtansp.a:libs/tans_pr.o libs/tans_0x.o ar rcvs libs/libtansp.a libs/tans_pr.o libs/tans_0x.o libs/tans_pr.o:src/tans_pr.c gcc -c src/tans_pr.c -I include/ -o libs/tans_pr.o libs/tans_0x.o:src/tans_0x.c gcc -c src/tans_0x.c -I include/ -o libs/tans_0x.o # Generate using dynamic library. bin/myod_so:src/main.c libs_so/libtansp.so gcc src/main.c libs_so/libtansp.so -I include/ -o bin/myod_so libs_so/libtansp.so:libs_so/tans_pr.o libs_so/tans_0x.o gcc -shared -o libs_so/libtansp.so libs_so/tans_pr.o libs_so/tans_0x.o libs_so/tans_pr.o:src/tans_pr.c gcc -fPIC -c -I include/ src/tans_pr.c -o libs_so/tans_pr.o libs_so/tans_0x.o:src/tans_0x.c gcc -fPIC -c -I include/ src/tans_0x.c -o libs_so/tans_0x.o# This is a make file. # Generate using static library. myod:bin/myod ln -s bin/myod myod bin/myod:src/main.c libs/libtansp.a gcc src/main.c libs/libtansp.a -I include/ -o bin/myod libs/libtansp.a:libs/tans_pr.o libs/tans_0x.o ar rcvs libs/libtansp.a libs/tans_pr.o libs/tans_0x.o libs/tans_pr.o:src/tans_pr.c gcc -c src/tans_pr.c -I include/ -o libs/tans_pr.o libs/tans_0x.o:src/tans_0x.c gcc -c src/tans_0x.c -I include/ -o libs/tans_0x.o # Generate using dynamic library. bin/myod_so:src/main.c libs_so/libtansp.so gcc src/main.c libs_so/libtansp.so -I include/ -o bin/myod_so libs_so/libtansp.so:libs_so/tans_pr.o libs_so/tans_0x.o gcc -shared -o libs_so/libtansp.so libs_so/tans_pr.o libs_so/tans_0x.o libs_so/tans_pr.o:src/tans_pr.c gcc -fPIC -c -I include/ src/tans_pr.c -o libs_so/tans_pr.o libs_so/tans_0x.o:src/tans_0x.c gcc -fPIC -c -I include/ src/tans_0x.c -o libs_so/tans_0x.o
直接使用 Linux$ make
默認製做靜態庫,在5-12行前加 #
使用 Linux$ make
可製做動態庫。命令行
make 製做靜態庫:
設計
make 製做動態庫:
指針
Linux$ ln -s bin/myod myod
在項目文件夾下建立對於 bin/myod 的連接,可直接 ./myod XXX
運行。
輸入 Linux$ ls -l myod
可看到:
lrwxrwxrwx 1 yogile yogile 8 9月 28 15:32 myod -> bin/myod
./myod byte_txt/byte_0.txt
./myod byte_txt/byte_11.txt
./myod byte_txt/byte_16.txt
./myod byte_txt/byte_more.txt
編譯連接生成可執行文件時沒有問題,但在運行時報錯:
[yogile@yogile-pc MyOD]$ ./myod byte_txt/byte_0.txt 段錯誤 (核心已轉儲)
main.c
中的命令行參數輸入錯誤,致使訪問不存在的內存地址。int main(char *argv[]) { printf("args[1] = %s",argv[1]); ... }
int main(int argc, char *argv[]) {...
爲了斷定文件的字符是否讀完,我想得是沒有字符複製給 char_perline[i]
,其值爲空,但報錯:
[yogile@yogile-pc M[yogile@yogile-pc src]$ gcc main.c -o main.out main.c: 在函數‘main’中: main.c:23:35: 警告:比較指針和整數 23 | for (i=0; char_perline[i] != NULL; i++) { | ^~ main.c:29:35: 警告:比較指針和整數 29 | for (i=0; char_perline[i] != NULL; i++) { |
問題緣由分析:
錯誤是比較了指針和整數。
實際上,我使用的 while循環的條件是 (ch = fgetc(fp)) != EOF
。當文件讀完時,循環直接中止,再也不賦值給 char_perline[i]
。
問題解決方法:
在賦值前,將 char char_perline[]
的每一項初始化爲 \0
,\0
的16進制編碼是 00,NULL
改爲 '\0'
。
[yogile@yogile-pc MyOD]$ make gcc src/main.c libs/libtansp.a -I include/ -o bin/myod src/main.c: 在函數‘main’中: src/main.c:29:17: 警告:隱式聲明函數‘tans_0x’ [-Wimplicit-function-declaration] 29 | tans_0x(char_perline, 16); | ^~~~~~~
問題緣由分析:
缺乏聲明 tans_0x()
函數的頭文件。
問題解決方法:
添加聲明 tans_0x()
函數的頭文件:# include "tansp.h"
。
[yogile@yogile-pc MyOD]$ ./myod byte_txt/byte_0.txt 7dffffffeb6750 0000563f 7dffffffeb60ffffffa0 0000563f 37777777760 [yogile@yogile-pc MyOD]$ ./myod byte_txt/byte_11.txt 000000 34333231 38373635 5f0a6139 00005633 1 2 3 4 5 6 7 8 9 a \n 000013
int main(/* 命令行參數 */) { if (/* 打開文件失敗條件*/) { // 結束程序 } while(/* 條件 */) { // 調用tans_0x(); // 調用tans_pr(); } // 輸出最後一字符的字節序號 return 0; }
其中第 9 行 // 輸出最後一字符的字節序號
,在實際調用中 tans_0x(char_perline, 16);
向函數中傳遞了16個字節數據,但實際數據字符並無16個字節。因此輸出時輸出沒賦值的 char_perline[i]
時,輸出亂碼。
flag_change = 0
,只要while語句運行,就 flag_change++
。添加 if 語句,進行判斷剔除。if (flag_change != 0) { if (i < 16) { tans_0x(char_perline, i); tans_pr(char_perline, i); printf("\n"); } printf("%07o\n",16*(j-1)+i); } else { printf("0000000\n"); }