程設作業:
從txt檔案讀入一個n,n<=22,程式輸出3欄的nxn乘法表寫回原始txt檔案。
參考解法:
1. 三欄的99乘法表
首先需要兩個變數來跑for迴圈(可以是i,j或x,y隨便)
i j i*j
------------
1 x 1 = 1
1 x 2 = 2
1 x 3 = 3
...
1 x 9 = 9
2 x 1 = 2
...
9 x 9 = 81
for的語法
for(計數器;執行條件;計數器增減){ }
Ex: for(int i=1;i<=9;i=i+3){ }
這個for是在說
計數器i剛開始是1
符合1<=9
然後開始執行{ }裡面的程式
執行完以後i=i+3 所以i=4
符合4<=9
再次執行{ }裡面的程式
then i=i+3 也就是i=7
符合7<=9
執行 { }
i=i+3 → i=10
10<=9 不符合 所以跳出迴圈
降子迴圈總共跑3次
回到乘法表
利用兩個for組成的巢狀迴圈
for(int i=1;i<=9;i++){
for(int j=1;j<=9;j++){
printf("%2dx%2d=%3d\n",i,j,i*j);
}
printf("\n");
}
i=1,2,3...9,每一個i都會有j=1,2,3...9
降子i,j對應起來剛好是1x1,1x2...2x1,2x2,....9x9
第一個printf是把i,j,ixj分別輸出然後補上一個換行
第二個printf是在1x9跟2x1、2x9跟3x1....8x9跟9x1之間多補上一個換行
講解一下 printf的用法
型1 printf(字串);
直接輸出字串 Ex printf("第一行\n第二行");
螢幕會顯示
第一行
第二行
型2 printf(格式,變數);
Ex printf("a=%d",a);
降子會把變數a的內容顯示在螢幕上
變數也可以有很多個
格式的部份
常用的有%d(整數)、%f(浮點數)、%c(字元)、%s(字串)
詳細的內容請參閱投影片
那這裡先解釋上面程式裡面的printf("%2dx%2d=%3d",i,j,i*j);
%2d、%3d代表說一個整數用空白補滿2or3格 例如說3輸出成 3;12輸出成 12
達到各位數對齊的效果
目前為止程式只把99乘法表輸出成1欄
那現在我們把它改成3欄
i j i*j i+1 j (i+1)*j i+2 j (i+2)*j
---------------------------------------
1 x 1 = 1 2 x 1 = 2 3 x 1 = 3
1 x 2 = 2 ...
...
1 x 9 = 9 ...
4 x 1 = 4 5 x 1 = 5 ...
...
7 x 9 = 63 8 x 9 = 72 9 x 9 = 81
對照前一個1欄的99乘法表
i是控制直的下來用的 j是控制每一個i裡面的x1~x9
所以說改成三欄的話 i=1,4,7
程式就是
for(int i=1;i<=9;i+=3){
for(int j=1;j<=9;j++){
printf("%2dx%2d=%3d\t%2dx%2d=%3d\t%2dx%2d=%3d\n",i,j,i*j,i+1,j,(i+1)*j,
i+2,(i+2)*j);
}
printf("\n");
}
然後我們發現 第一個printf裡面其實重複的三次相似的輸出 可以改成for迴圈
( 只做99乘法表可以簡單的降打就好 但是後面的nxn的話需要用到for的特性 )
for(int i=1;i<=9;i+=3){
for(int j=1;j<=9;j++){
for(int k=i;k<=i+2;k++){
printf("%2dx%2d=%3d\t",k,j,k*j);
}
printf("\n");
}
printf("\n");
}
好 3欄的99乘法表OK囉
2.3欄的nxn乘法表
先考慮固定的n ( 之後要把n改成鍵盤或檔案輸入 )
int n=11;
for(int i=1;i<=n;i+=3){
for(int j=1;j<=n;j++){
for(int k=i;k<=i+2;k++){
printf("%2dx%2d=%3d\t",k,j,k*j);
}
printf("\n");
}
printf("\n");
}
先改i和j的for條件
程式跑完之後發現
1x1~1x11,2x1~2x11....到11x11都OK 但是12x1~12x11也跑出來了
問題出在k
因為k的for條件是i+2
這裡的i=1,4,7,10 根據上面的條件 k在i=10的時候 k=10,11,12
12已經超過n了 所以我們要改一下k在for的條件
for(int k=i;k<=i+2 && k<=n;k++)
&&的意思是and(且) 也就是說 k<=i+2 和 k<=n 要同時是true時 for才會跑
那降k=10符合10<=10+2和10<=11
k=11符合11<=10+2和11<=11
k=12時12<=10+2 and 12<=11就會是false 目標達成
接下來 n要能讓使用者從鍵盤輸入
介紹一下 scanf的用法
跟printf型2很像
scanf(格式,變數指標)
Ex scanf("%d",&a);
降子打99按enter 就會把99存到整數a裡面
把上面的程式int n=11的地方改成
int n;
printf("nxn的乘法表 請輸入一個小於22的整數n");
scanf("%d",&n);
nxn的部份也搞定啦
3. 從txt檔案讀取n,然後把nxn的乘法表存回txt檔案
上面的程式都OK的話
先介紹一下存檔讀檔的語法
讀檔/存檔
FILE* f;
f=fopen(檔名,模式);
<利用fscanf讀檔;fprintf存檔>
fclose(f);
檔名最好是用完整的檔名 像是這樣 D:\\my documents\\a.txt 或是 C:\\1.txt 之類的
記得路徑的\要打成\\ 因為\在printf和scanf裡面有特殊意義 例如\n是換行
模式有 r,w,a 三種 r讀檔 w存檔(先清空檔案) a存檔(寫在之前後面不清空原始檔)
f是檔案指標 存檔讀檔都會用到 不一定要用f 命名規則跟一般變數一樣
fscanf對應scanf 語法一樣 一個輸出到檔案 另一個是螢幕
fscanf跟scanf不一樣的地方在多需要一個檔案指標
( 不然程式怎麼知道要寫到哪個檔案 )
fprintf也是一樣 語法一樣 只比printf多一個檔案指標
現在把第2部分的程式scanf("%d",&n)的部份改成
int n;
FILE* f;
f=fopen("c:\\a.txt","r");
fscanf(f,"%d",&n);
fclose(f);
那後面因為是要寫在檔案裡面
所以所有的printf都改成fprintf
for(int i...之前加上存檔程序
FILE* f;
f=fopen("c:\\a.txt","a");
然後把for裡面的printf改成fprintf
printf("%2dx%2d=%3d",k,j,k*j);
改成
fprintf(f,"%2dx%2d=%3d",k,j,k*j);
還有
printf("\n");
改成
fprintf(f,"\n");
最後記得在程式結束以前把檔案關閉 才完成存檔程序喔
加上 fclose(f); 就可以
注意:因為老師要求的是從檔案裡面讀n
所以要先建一個txt檔 裡面已經存好n 不然會當機
或者不要用fscanf 直接從鍵盤輸入(scanf)
呼 講解完了 大家有什麼問題回文OR直接MSN密我吧
上學期直接PO程式碼的作法大家做的只能是抄
那我現在把我整個想法和做法都PO出來 順便把每一行的意義跟語法都解釋清楚了
作法並不唯一 大家可以試著用自己的想法去解題
只有想法不知道怎麼寫成程式的話也可以用MSN問我
希望大家都能看懂然後自己寫出程式來囉