(问题)c语言现代方法2th,自己编写的reminder.c程序 找错/修改/拓展延伸
生活随笔
收集整理的這篇文章主要介紹了
(问题)c语言现代方法2th,自己编写的reminder.c程序 找错/修改/拓展延伸
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
這是問(wèn)題?
下面的程序1.c是自己編寫(xiě)的,運(yùn)行結(jié)果如下:
輸入:
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?問(wèn)題:程序1.c錯(cuò)在哪里了?
//程序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) { //用整數(shù)輸入日期,一會(huì)利用sprintf轉(zhuǎn)換成char * int day,i,j; char remind[MSG_LEN + 1]; int count = 0; //there is a space character after the day//錯(cuò)誤1:這里有點(diǎn)不恰當(dāng),應(yīng)該是day_str[3]就可以了,存放兩位數(shù)的字符串,維度是3剛好 char day_str[4];scanf("%2d",&day); readline(remind,MSG_LEN + 1); //轉(zhuǎn)換day,使得它成為char *,sprintf的功能是把格式化字符串打印到字符串中, //sprintf第一個(gè)就是要打印的目的字符串(打印到哪),其余的和以前的printf一樣//錯(cuò)誤2:day應(yīng)該以2位的方法輸出,應(yīng)該改成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;//下面這行是多出來(lái)的,不知道自己怎么想的,多這么一行,在reminders末尾加一行“”,結(jié)果錯(cuò)加到這里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) { //用整數(shù)輸入日期,一會(huì)利用sprintf轉(zhuǎn)換成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); //轉(zhuǎn)換day,使得它成為char *,sprintf的功能是把格式化字符串打印到字符串中, //sprintf第一個(gè)就是要打印的目的字符串(打印到哪),其余的和以前的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);} }運(yùn)行 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"大功告成
心得體會(huì):
(1)本文輸出的時(shí)候,日期和reminder之間有一個(gè)空格,這個(gè)空格在把日期copy到reminders之后,在strcat之前,用strcat多拼接一個(gè)空格就可以,也就是,reminders的每行拼接順序是
? ? ? ? ? ? ? ? ? ? ? ? 日期? +? 空格? ? + reminder
(2)在讀取字符串的時(shí)候,也就是設(shè)計(jì)readline的時(shí)候,務(wù)必考慮是否忽略開(kāi)頭的空格,這個(gè)程序是忽略開(kāi)頭的空格的,為的是無(wú)論輸入的時(shí)候即使是亂七八糟的,但是輸入的時(shí)候依然是整齊的(但是數(shù)字部分始終2位,注意,不夠后面則空格)
例如,重新運(yùn)行程序,輸出仍然很整齊。
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); } }說(shuō)明:讀取字符跳過(guò)空格可以簡(jiǎn)單地用下面實(shí)現(xiàn)
scanf(" %c",&ch);稍微改進(jìn)下性能:?
#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,"時(shí)");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); } }上面程序冗余代碼太多,下面這個(gè)
#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,那么會(huì)有 數(shù)據(jù)殘留在內(nèi)存內(nèi),造成的后果是自動(dòng)執(zhí)行循環(huán),因?yàn)閮?nèi)存中有數(shù)據(jù)可供scanf執(zhí)行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,"時(shí)"); 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); } }教訓(xùn):如果使用continue結(jié)束一次循環(huán),后面絕對(duì)不能跟讀入數(shù)據(jù)的語(yǔ)句,總體來(lái)說(shuō),continue的時(shí)候,內(nèi)存中不能有殘留數(shù)據(jù)。
最好等數(shù)據(jù)語(yǔ)句(例如scanf,gets,gechar等執(zhí)行完完整的一次后,才能continue,break一般無(wú)此限制,反正也退出循環(huán)了。)
如果本最后這個(gè)程序中,把continue語(yǔ)句放在readline()語(yǔ)句之前,就會(huì)犯這種錯(cuò)誤,也就是變量reminder(在readline中)還沒(méi)有來(lái)得及讀入自己變量,但是變量已經(jīng)回車(chē)前輸出了,所以這個(gè)變量就會(huì)殘留在內(nèi)存內(nèi)。導(dǎo)致程序執(zhí)行出乎意料的結(jié)果
總結(jié)
以上是生活随笔為你收集整理的(问题)c语言现代方法2th,自己编写的reminder.c程序 找错/修改/拓展延伸的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: pygame 学习check_event
- 下一篇: vim从0开始