close
可能因為老江也是做OS又超愛linux的關係 所以作業都跟linux系統有關
作業主要是要我們實作出unix系統中xxd指令的功能
xxd的用法如下:
這個作業主要是要我們瞭解
1.利用C++中stream的觀念來對檔案做存取操作的動作
2.利用C++的一些I/O函式對程式結果做排版
3.程式切割的用途及makefile的撰寫
-----------------------------------------------------------------------------------------------------
我在這次作業的作法程序就是
開啟目標檔案->逐字讀取->滿一行(16個字),印出結果->換行
︿
|____________________________|
1.stream的開啟及操作
C++對於輸出輸入的資料都以資料流的方式來控制
例如最常看到的"cout"
cout<<"moli";
上面就是把"moli"這字串流向cout這個函式中做處理
再來就是這次作業要做的事:把一個檔案以資料流的方式開啟
ifstream inStream; //宣告一個input stream型態的變數 變數名稱為inStream
作業主要是要我們實作出unix系統中xxd指令的功能
xxd的用法如下:
$ xxd Makefile
紅色表示我們要轉換的文件名稱 ,之後將文件內容轉成16進位格式
輸出畫面:
紅色表示我們要轉換的文件名稱 ,之後將文件內容轉成16進位格式
輸出畫面:
0000000: 2320 4120 7361 6d70 6c65 206d 616b 6520 # A sample make
0000010: 6669 6c65 2066 6f72 2074 6865 2068 6f6d file for the hom
0000020: 6577 6f72 6b20 6173 7369 676e 6d65 6e74 ework assignment
0000030: 0a0a 5352 4353 203a 3d20 2428 7368 656c ..SRCS := $(shel
0000040: 6c20 6c73 202a 2e63 7070 290a 4f42 4a53 l ls *.cpp).OBJS
0000050: 203a 3d20 2428 5352 4353 3a2e 6370 703d := $(SRCS:.cpp=
0000060: 2e6f 290a 4558 4543 203a 3d20 6d79 7878 .o).EXEC := myxx
0000070: 640a 0a61 6c6c 3a20 2428 4558 4543 290a d..all: $(EXEC).
0000080: 0a6d 7978 7864 3a20 2428 4f42 4a53 290a .myxxd: $(OBJS).
*以第一行為例 : #的16進位就是23 空白的16進位為20
一行可分為三個部份
1.行數: 0000000,0000010.....
2.16進位格式
3.文件內容 無法印出部份(如空白)用'.'表示
-----------------------------------------------------------------------------------------------------*以第一行為例 : #的16進位就是23 空白的16進位為20
一行可分為三個部份
1.行數: 0000000,0000010.....
2.16進位格式
3.文件內容 無法印出部份(如空白)用'.'表示
這個作業主要是要我們瞭解
1.利用C++中stream的觀念來對檔案做存取操作的動作
2.利用C++的一些I/O函式對程式結果做排版
3.程式切割的用途及makefile的撰寫
-----------------------------------------------------------------------------------------------------
我在這次作業的作法程序就是
開啟目標檔案->逐字讀取->滿一行(16個字),印出結果->換行
︿
|____________________________|
1.stream的開啟及操作
C++對於輸出輸入的資料都以資料流的方式來控制
例如最常看到的"cout"
cout<<"moli";
上面就是把"moli"這字串流向cout這個函式中做處理
再來就是這次作業要做的事:把一個檔案以資料流的方式開啟
ifstream inStream; //宣告一個input stream型態的變數 變數名稱為inStream
inStream.open(Source); //將名稱為Source的檔案打開 並將inSream指向此檔案
開啟成功後 便使用get()這個Stream的member function一字一字的讀進來
while(inStream.get(ch)) { //將InStream所讀的字元放進ch
2.輸出結果排版
輸出結果我分成兩部分的函式來進行
(1)行數+16進位格式 myprintf(...)
(2)文件內容 HumanRead(...)
3.程式切割&Makefile
作業要求整個程式需分為main.cpp , myxxd.cpp , myxxd.h
main.cpp也就是我們的主程式
他其實就是一個driver.要去"驅動"我們要的功能
只做驅動的動作(也就是呼叫我們的功能函式) 其他事就不做了
所以一般來說 main都是短短幾行 且不對資料做任何運算處理的動作
myxxd.h myxxd.cpp
所謂標頭檔(header file)其實就是提供給使用者知道的介面(interface)
裡面大多只有功能函式的宣告
使用者只要知道當include這個標頭檔後有哪些功能可以用及丟什麼參數就好
ex: myxxd.h
最後Makefile比較要記的就是make dep
上面的動作主要是把在整個程式編譯時所建立的相依性(dependency)
寫入.depend裡 我們可以由這檔案看到各程式碼檔案之間的關係
開啟成功後 便使用get()這個Stream的member function一字一字的讀進來
while(inStream.get(ch)) { //將InStream所讀的字元放進ch
ubuffer[count]=ch; //將ch存放到ubuffer (將來要印出文件內容要用的)
myprint(ch,count,LineCnt); //將目前所讀到的字元及行數傳入myprint函式做輸出
myprint(ch,count,LineCnt); //將目前所讀到的字元及行數傳入myprint函式做輸出
count++; //count為紀錄字元數
if(count<LineLen) continue; //未滿16個(一行的字元數)就繼續做讀取字元的動作
else {
cout<<" "; //滿一行 印出之前所讀的文件內容
HumanRead(ubuffer,count);
count=0;
LineCnt++;
cout<<endl;
}
}
}
2.輸出結果排版
輸出結果我分成兩部分的函式來進行
(1)行數+16進位格式 myprintf(...)
(2)文件內容 HumanRead(...)
void myprint(char ch,int count,int LineCnt) //print hex format
{
if(count==0) cout<<setw(6)<<setfill('0')<<(hex)<<LineCnt<<setw(2)<<setfill('0')<<":"<<" ";
//假如尚未讀入字元 印出行數
//假如尚未讀入字元 印出行數
cout<<hex<<right<<setw(2)<<setfill('0')<<(int)ch;
//印出16進位的前一個部份
//印出16進位的前一個部份
if((count%2)!=0) cout<<" ";
//印出16進位的後一個部份
//印出16進位的後一個部份
}
void HumanRead(unsigned char* ubuffer,int count) //human readable part
{
for(int q=0;q<count;q++) { //將之前ubuffer存入的字元印出
if(isprint(ubuffer[q])) cout<<ubuffer[q];
else cout<<"."; //若無法印出 以"".代替
}
}
}
3.程式切割&Makefile
作業要求整個程式需分為main.cpp , myxxd.cpp , myxxd.h
main.cpp也就是我們的主程式
他其實就是一個driver.要去"驅動"我們要的功能
只做驅動的動作(也就是呼叫我們的功能函式) 其他事就不做了
所以一般來說 main都是短短幾行 且不對資料做任何運算處理的動作
myxxd.h myxxd.cpp
所謂標頭檔(header file)其實就是提供給使用者知道的介面(interface)
裡面大多只有功能函式的宣告
使用者只要知道當include這個標頭檔後有哪些功能可以用及丟什麼參數就好
ex: myxxd.h
#include<iostream> //以下為要用到的其他函式庫
#include<fstream>
#include<iomanip>
#include<ctype.h>
using namespace std;
void myxxd(char* Target); // 程式設計者自訂的函式宣告
void myprint(char ch,int count,int LineCnt);
void HumanRead(char* ubuffer);
而上述那些功能函式的實現(Implement)
也就是怎麼去完成那些功能的實際作法等
就寫在myxxd.cpp裡
而上述那些功能函式的實現(Implement)
也就是怎麼去完成那些功能的實際作法等
就寫在myxxd.cpp裡
最後Makefile比較要記的就是make dep
dep:
$(CXX) -M $(SRCS) >depend
上面的動作主要是把在整個程式編譯時所建立的相依性(dependency)
寫入.depend裡 我們可以由這檔案看到各程式碼檔案之間的關係
全站熱搜
留言列表