精華區beta NTUE-CS99 關於我們 聯絡資訊
程設作業: 從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問我 希望大家都能看懂然後自己寫出程式來囉