(问题)c语言现代方法2th,自己编写的reminder.c程序 找错/修改/拓展延伸
生活随笔
收集整理的這篇文章主要介紹了
(问题)c语言现代方法2th,自己编写的reminder.c程序 找错/修改/拓展延伸
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這是問題?
下面的程序1.c是自己編寫的,運行結果如下:
輸入:
24 susan's birthday 5 6:00 - Dinner with Marge and RUSS 25 Movie - "Chinatown" 7 10:30 - Dental appointment 5 Saturday 0輸出:
24 Saturday?問題:程序1.c錯在哪里了?
//程序1.c #include <stdio.h> #include <string.h>#define MAX_REMINDERS 50 #define MSG_LEN 60int read(char (*p)[MSG_LEN + 3],int n); int readline(char *,int n); void print(char (*p)[MSG_LEN + 3]); int main() { char reminders[MAX_REMINDERS + 1][MSG_LEN+ 3];//2 seat for date,others for reminders read(reminders,MAX_REMINDERS + 1); print(reminders);return 0; }int read(char (*p)[MSG_LEN + 3],int n) { //用整數輸入日期,一會利用sprintf轉換成char * int day,i,j; char remind[MSG_LEN + 1]; int count = 0; //there is a space character after the day//錯誤1:這里有點不恰當,應該是day_str[3]就可以了,存放兩位數的字符串,維度是3剛好 char day_str[4];scanf("%2d",&day); readline(remind,MSG_LEN + 1); //轉換day,使得它成為char *,sprintf的功能是把格式化字符串打印到字符串中, //sprintf第一個就是要打印的目的字符串(打印到哪),其余的和以前的printf一樣//錯誤2:day應該以2位的方法輸出,應該改成sprintf(day_str,"%2d",day); sprintf(day_str,"%3d",day);while(day != 0){ for(i = 0;i < count; ++i){if(strcmp(p[i],day_str) > 0) break; }for(j = count - 1;j >= i;--j){strcpy(p[j+1],p[j]); }strcpy(p[i],day_str);strcat(p[i],remind);++ i;//下面這行是多出來的,不知道自己怎么想的,多這么一行,在reminders末尾加一行“”,結果錯加到這里strcpy(p[i],"");count ++;scanf("%2d",&day);readline(remind,MSG_LEN + 1);}return count; }//whileint readline(char *p,int n) { char ch; int cnt = 0; while((ch = getchar()) != '\n' && cnt < n){ *p ++ = ch;++ cnt;}*p = '\0';return cnt; }void print(char (*p)[MSG_LEN + 3]) { for(; strcmp(*p,"") != 0; ++p){printf("%s\n",*p);} }改正后的程序:
//1.c #include <stdio.h> #include <string.h>#define MAX_REMINDERS 50 #define MSG_LEN 60int read(char (*p)[MSG_LEN + 3],int n); int readline(char *,int n); void print(char (*p)[MSG_LEN + 3]); int main() { char reminders[MAX_REMINDERS + 1][MSG_LEN+ 3];//2 seat for date,others for reminders read(reminders,MAX_REMINDERS + 1); print(reminders);return 0; }int read(char (*p)[MSG_LEN + 3],int n) { //用整數輸入日期,一會利用sprintf轉換成char * int day,i,j; char remind[MSG_LEN + 1]; int count = 0; //there is a space character after the day char day_str[3]; scanf("%2d",&day); readline(remind,MSG_LEN + 1); //轉換day,使得它成為char *,sprintf的功能是把格式化字符串打印到字符串中, //sprintf第一個就是要打印的目的字符串(打印到哪),其余的和以前的printf一樣 sprintf(day_str,"%2d",day); while(day != 0){ for(i = 0;i < count; ++i){if(strcmp(p[i],day_str) > 0) break; }for(j = count - 1;j >= i;--j){strcpy(p[j+1],p[j]); }strcpy(p[i],day_str);strcat(p[i]," ");strcat(p[i],remind);count ++;scanf("%2d",&day);readline(remind,MSG_LEN + 1);sprintf(day_str,"%2d",day);}strcpy(p[count],"");return count; }//whileint readline(char *p,int n) {char ch; int cnt = 0; ch = getchar(); while(ch != '\n' && cnt < n){if(ch == ' ' && cnt == 0)ch = getchar();else{*p ++ = ch;++ cnt; ch = getchar(); } }*p = '\0';return cnt; }void print(char (*p)[MSG_LEN + 3]) { for(; strcmp(*p,"") != 0; ++p){printf("%s\n",*p);} }運行 gcc 1.c -o 123
24 Susan's birthday 5 6:00 -Dinner with Marge and Russ 26 Movie - "Chinatown" 7 10:30 - Dental appointment 5 Saturday class 12 Saturday class 05 Saturday class5 6:00 -Dinner with Marge and Russ7 10:30 - Dental appointment 12 Saturday class 24 Susan's birthday 26 Movie - "Chinatown"大功告成
心得體會:
(1)本文輸出的時候,日期和reminder之間有一個空格,這個空格在把日期copy到reminders之后,在strcat之前,用strcat多拼接一個空格就可以,也就是,reminders的每行拼接順序是
? ? ? ? ? ? ? ? ? ? ? ? 日期? +? 空格? ? + reminder
(2)在讀取字符串的時候,也就是設計readline的時候,務必考慮是否忽略開頭的空格,這個程序是忽略開頭的空格的,為的是無論輸入的時候即使是亂七八糟的,但是輸入的時候依然是整齊的(但是數字部分始終2位,注意,不夠后面則空格)
例如,重新運行程序,輸出仍然很整齊。
5 Saturday class 5 6:00 -Dinner with Marge and Russ 7 10:30 - Dental appointment 12Saturday class 26 Movie - "Chinatown" 12 Saturday class 05 6:00 -Dinner with Marge and Russ5 Saturday class7 10:30 - Dental appointment 12 Saturday class 12 Saturday class 26 Movie - "Chinatown"第二部分:延伸拓展
解決本章編程題2題
#include <stdio.h> #include <string.h>#define MSG_LEN 100 #define MAX_REMINDERS 1000int readline(char *,int ); int read(char (*p)[MSG_LEN + 11],int n); void print(char (*p)[MSG_LEN + 11]);int main() { char reminders[MAX_REMINDERS + 1][MSG_LEN + 11]; read(reminders,MAX_REMINDERS + 1); print(reminders);return 0; }int read(char (*p)[MSG_LEN + 11],int n) { int month,day,time_24_hour; char reminder[MSG_LEN + 1]; char str_month[3],str_day[3],str_time_24_hour[7]; int i,j,count = 0; char prefix_number[13];printf("Enter month and day and time and reminder:\n\ 例如:9 26 131313 it's time to work:");scanf("%d",&month); sprintf(str_month,"%2d",month); scanf("%d",&day); sprintf(str_day,"%2d",day);//if month ==0 and day == 0,then return 0 if(month == 0 && day == 0)return 0; scanf("%d",&time_24_hour); sprintf(str_time_24_hour,"%6d",time_24_hour); readline(reminder,MSG_LEN + 1);while(month != 0){ strcpy(prefix_number,str_month);strcat(prefix_number," ");strcat(prefix_number,str_day);strcat(prefix_number," ");strcat(prefix_number,str_time_24_hour);for(i = 0; i < count;++i) {if(strcmp(prefix_number,p[i]) < 0)break; }for(j = count -1;j >= i; --j){strcpy(p[j + 1],p[j]); }strcpy(p[i],prefix_number);strcat(p[i]," ");strcat(p[i],reminder);++ count;scanf("%d",&month);scanf("%d",&day);if(month == 0 && day == 0)break;scanf("%d",&time_24_hour);if(month == 0 && day == 0)break;readline(reminder,MSG_LEN +1);sprintf(str_month,"%2d",month);sprintf(str_day,"%2d",day);sprintf(str_time_24_hour,"%6d",time_24_hour);}/* add a "" in the end of p */strcpy(p[count],"");return count; } int readline(char *p,int n) { char ch; int cnt = 0;while((ch = getchar()) != '\n' && cnt < n){if(ch == ' ' && cnt == 0);else{*p ++ = ch;++ cnt; } } *p = '\0'; return cnt; } void print(char (*p)[MSG_LEN + 11]) { for(;strcmp(*p,"") != 0;++ p){printf("%s\n",*p); } }說明:讀取字符跳過空格可以簡單地用下面實現
scanf(" %c",&ch);稍微改進下性能:?
#include <stdio.h> #include <string.h> #include <stdbool.h> #define MSG_LEN 100 #define MAX_REMINDERS 1000int readline(char *,int ); int read(char (*p)[MSG_LEN + 11],int n); void print(char (*p)[MSG_LEN + 11]);int main() { char reminders[MAX_REMINDERS + 1][MSG_LEN + 11]; read(reminders,MAX_REMINDERS + 1); print(reminders);return 0; }int read(char (*p)[MSG_LEN + 11],int n) { int month,day,hour,minute; char reminder[MSG_LEN + 1]; //change char str_month[3],str_day[3]; char str_hour[3],str_minute[3];//str_time_24_hour[7]; int i,j,count = 0; char prefix_number[20];printf("Enter month day hour minute reminder(0 0 to break):\n"); while(true) {scanf("%d",&month);sprintf(str_month,"%2d",month);scanf("%d",&day);sprintf(str_day,"%2d",day);//if month ==0 and day == 0,then return 0if(month == 0 && day == 0)return 0;//change //scanf("%d",&time_24_hour);scanf("%d",&hour);scanf("%d",&minute);sprintf(str_hour,"%2d",hour);sprintf(str_minute,"%2d",minute);//sprintf(str_time_24_hour,"%6d",time_24_hour);readline(reminder,MSG_LEN + 1);if(day > 31 || day < 0){ printf("\ninvalid input,again.\n");continue;}else break; }//while while(month != 0){strcpy(prefix_number,str_month);strcat(prefix_number," ");strcat(prefix_number,str_day);strcat(prefix_number," ");strcat(prefix_number,str_hour);strcat(prefix_number,"時");strcat(prefix_number,str_minute);strcat(prefix_number,"分 ");for(i = 0; i < count;++i) {if(strcmp(prefix_number,p[i]) < 0)break; }for(j = count -1;j >= i; --j){strcpy(p[j + 1],p[j]); }strcpy(p[i],prefix_number);strcat(p[i],reminder);++ count;month = 0;day = 0;hour = 0;minute= 0;while(true){ scanf("%d",&month);scanf("%d",&day);if(month == 0 && day == 0)break;scanf("%d",&hour);if(month == 0 && day == 0)break;scanf("%d",&minute); readline(reminder,MSG_LEN +1);sprintf(str_month,"%2d",month);sprintf(str_day,"%2d",day);sprintf(str_hour,"%2d",hour);sprintf(str_minute,"%2d",minute);if(day > 31 || day < 0){printf("\nvalid input,again.\n");continue;}elsebreak;}//while}/* add a "" in the end of p */strcpy(p[count],"");return count; } int readline(char *p,int n) { char ch; int cnt = 0;while((ch = getchar()) != '\n' && cnt < n){if(ch == ' ' && cnt == 0);else{*p ++ = ch;++ cnt; } } *p = '\0'; return cnt; } void print(char (*p)[MSG_LEN + 11]) { for(;strcmp(*p,"") != 0;++ p){printf("%s\n",*p); } }上面程序冗余代碼太多,下面這個
#include <stdio.h> #include <string.h> #include <stdbool.h> #define MSG_LEN 100 #define MAX_REMINDERS 1000int readline(char *,int ); int read(char (*p)[MSG_LEN + 11],int n); void print(char (*p)[MSG_LEN + 11]);int main() { char reminders[MAX_REMINDERS + 1][MSG_LEN + 11]; read(reminders,MAX_REMINDERS + 1); print(reminders);return 0; }int read(char (*p)[MSG_LEN + 11],int n) { int month,day,hour,minute; char reminder[MSG_LEN + 1]; char str_month[3],str_day[3]; char str_hour[3],str_minute[3]; int i = 0,j = 0,count = 0; char prefix_number[20];while(true) { //set month,day,hour,minute to 0 month = 0; day = 0; hour =0; minute = 0;// input printf("Enter month day hour minute(0 0 to quit):\n"); scanf("%d",&month); scanf("%d",&day); if(month == 0 && day == 0)break;/* 一處 */ scanf("%d",&hour); scanf("%d",&minute);/* 二處 /readline(reminder,MSG_LEN + 1);/* ---------- 這 段 代 碼 能 放 在 下 面 的 注 釋 處------------*/ if(day > 31 || day < 0){printf("\ninvalid input,again.\n");continue; }/*----------------------------------------------------------------- 特別緊惕:如果上面這段代碼放在前一處、二處的任何一處,如果day輸入大于31,那么會有 數據殘留在內存內,造成的后果是自動執行循環,因為內存中有數據可供scanf執行1次 ------------------------------------------------------------------*///transform sprintf(str_month,"%2d",month); sprintf(str_day,"%2d",day); sprintf(str_hour,"%2d",hour); sprintf(str_minute,"%2d",minute);//set prefix_number strcpy(prefix_number,str_month); strcat(prefix_number,"月"); strcat(prefix_number,str_day); strcat(prefix_number,"日"); strcat(prefix_number,str_hour); strcat(prefix_number,"時"); strcat(prefix_number,str_minute); strcat(prefix_number,"分 ");//insert into for(i = 0;i < count;++ i)if(strcmp(p[i],prefix_number) > 0)break; for(j = count-1;j >= i; --j){strcpy(p[j + 1],p[j]); } strcpy(p[i],prefix_number); strcat(p[i],reminder); ++ count; }strcat(p[count],"");return count; } int readline(char *p,int n) { char ch; int cnt = 0;while((ch = getchar()) != '\n' && cnt < n){if(ch == ' ' && cnt == 0);else{*p ++ = ch;++ cnt; } } *p = '\0'; return cnt; } void print(char (*p)[MSG_LEN + 11]) { for(;strcmp(*p,"") != 0;++ p){printf("%s\n",*p); } }教訓:如果使用continue結束一次循環,后面絕對不能跟讀入數據的語句,總體來說,continue的時候,內存中不能有殘留數據。
最好等數據語句(例如scanf,gets,gechar等執行完完整的一次后,才能continue,break一般無此限制,反正也退出循環了。)
如果本最后這個程序中,把continue語句放在readline()語句之前,就會犯這種錯誤,也就是變量reminder(在readline中)還沒有來得及讀入自己變量,但是變量已經回車前輸出了,所以這個變量就會殘留在內存內。導致程序執行出乎意料的結果
總結
以上是生活随笔為你收集整理的(问题)c语言现代方法2th,自己编写的reminder.c程序 找错/修改/拓展延伸的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: pygame 学习check_event
- 下一篇: vim从0开始