鱼C论坛

 找回密码
 立即注册
查看: 1827|回复: 20

[已解决]使用字符数组处理字符串变量

[复制链接]
发表于 2019-8-12 21:12:19 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include <stdio.h>
  2. #include <string.h>
  3. #define MAX_REMIND 50
  4. #define MSG_LEN 60


  5. int main()
  6. {
  7.         char reminders[MAX_REMIND][MSG_LEN+3];
  8.         char day_str[3],msg_str[MSG_LEN+1];
  9.         int day[MAX_REMIND]={0},i,j=0,num_remind=0,ch,len=0;
  10.         char *p[MAX_REMIND];
  11.        
  12. /*
  13.         for(;;)
  14.         {
  15.                 printf("Enter the day and reminder:");
  16.                 scanf("%d",&day[j]);
  17.                 if(day[j]==0)
  18.                 break;
  19.                 sprintf(day_str,"%2d",day[j]);
  20.                 i=1;
  21.                 msg_str[0]=' ';
  22.                 while((ch=getchar())!='\n')
  23.                 {
  24.                         msg_str[i++]=ch;
  25.                        
  26.                 }
  27.                 msg_str[i]='\0';
  28.                 strcat(strcpy(reminders[j],day_str),msg_str);
  29.                 j++;       
  30.         }

  31. */
  32.        
  33.         for(i=0;i<j;i++)
  34.         {
  35.                 p[i]=reminders[i];
  36.                 len++;
  37.         }
  38.         ch=len-1;
  39.         while(ch>=0)
  40.         {
  41.                 j=-1;
  42.                 for(i=0;i<=ch-1;i++)
  43.                 {
  44.                         j=i+1;
  45.                         if(day[i]>day[j])
  46.                         {
  47.                                 p[i]=reminders[j];
  48.                                 p[j]=reminders[i];
  49.                         }
  50.                
  51.                 }
  52.                 ch=j;
  53.         }
  54.        
  55.         for(i=0;i<len;i++)
  56.         printf("%s\n",p[i]);
  57.        
  58.         return 0;
  59.        
  60. }
复制代码


/********************************************************************************************************************************************
我的问题出在(代码里用注释标记的那个for循环)
那部分代码想要实现:输入一个数字,(空格结束数字的输入)。然后是字符串信息(用回车结束)。把这两部分统一保存为字符串保存在二维数组里。
问题来了:只输入一条信息(然后输入数字0,可以退出这个for循环),如果输入2及以上的信息,再输入0,退不出这个循环。
请大家帮我看看,谢谢。
最佳答案
2019-8-13 00:18:51
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. #define MAX_REMIND 50
  5. #define MSG_LEN 60

  6. int main(void)
  7. {
  8.         char reminders[MAX_REMIND][MSG_LEN + 3]                             ;
  9.         char day_str[3] , msg_str[MSG_LEN + 1]                              ;
  10.         int day[MAX_REMIND]={0} , i , j = 0 , num_remind = 0 , ch , len = 0 ;
  11.         int tx                                                              ;
  12.         char * p[MAX_REMIND] , * px                                         ;

  13.         for(;;) {
  14.                 printf("Enter the day and reminder : ")                     ;
  15.                 scanf("%d" , & day[j])                                      ;
  16.                 if(day[j] == 0) break                                       ;
  17.                 while(day[j] > 99) day[j] /= 10                             ;
  18.                 sprintf(day_str , "%2d" , day[j])                           ;
  19.                 i = 0                                                       ;
  20.                 msg_str[i] = '\0'                                           ;
  21.                 while((ch = getchar()) != '\n') msg_str[i ++] = ch          ;
  22.                 msg_str[i]= '\0'                                            ;
  23.                 strcat(strcpy(reminders[j] , day_str) , msg_str)            ;
  24.                 j ++                                                        ;        
  25.         }
  26.         for(i = 0 ; i < j ; i ++) {
  27.                 p[i] = reminders[i]                                         ;
  28.                 len ++                                                      ;
  29.         }
  30.         for(i = 1 ; i < len ; i ++) {
  31.                 for(j = i ; j > 0 && day[j] < day[j - 1] ; j --) {
  32.                         tx = day[j]                                         ;
  33.                         day[j] = day[j - 1]                                 ;
  34.                         day[j - 1] = tx                                     ;
  35.                         px = p[j]                                           ;
  36.                         p[j] = p[j - 1]                                     ;
  37.                         p[j - 1] = px                                       ;
  38.                 }
  39.         }
  40.         for(i = 0 ; i < len ; i ++) printf("%s\n" , p[i])                   ;
  41. }
复制代码


      你是怎么弄的,看看我这里的运行实况:

  1. C:\Bin>g++ -o x2 x2.c

  2. C:\Bin>x2
  3. Enter the day and reminder : 13 1234
  4. Enter the day and reminder : 12 1234
  5. Enter the day and reminder : 11 1234
  6. Enter the day and reminder : 1588 1234
  7. Enter the day and reminder : 1789 1234
  8. Enter the day and reminder : 19870 1234
  9. Enter the day and reminder : 291876 1234
  10. Enter the day and reminder : 5 1234
  11. Enter the day and reminder : 2 1234
  12. Enter the day and reminder : 0
  13. 2 1234
  14. 5 1234
  15. 11 1234
  16. 12 1234
  17. 13 1234
  18. 15 1234
  19. 17 1234
  20. 19 1234
  21. 29 1234

  22. C:\Bin>
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-8-12 21:32:24 | 显示全部楼层
      你的描述很不清楚,用样例说话,比如,你希望键入什么样的东西时,循环继续,键入什么样的东西时,循环终止?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-12 21:35:05 | 显示全部楼层
jackz007 发表于 2019-8-12 21:32
你的描述很不清楚,用样例说话,比如,你希望键入哪些东西继续,键入哪些东西时终止循环。

比如 输入:“12 1234(回车)0”,这样可以退出循环
       输入:“ 12 1234(回车)13 1234(回车)0”,退不出循环
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-12 21:36:22 | 显示全部楼层
jackz007 发表于 2019-8-12 21:32
你的描述很不清楚,用样例说话,比如,你希望键入什么样的东西时,循环继续,键入什么样的东西时,循 ...

我想要输入多个信息,保存再二维数组里,可以退出这个循环。问题是退不出来
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-12 22:29:34 | 显示全部楼层
本帖最后由 jackz007 于 2019-8-12 22:37 编辑

    问题出在你的排序循环上了,就是下面这块代码:
  1.         ch=len-1;
  2.         while(ch>=0)
  3.         {
  4.                 j=-1;
  5.                 for(i=0;i<=ch-1;i++)
  6.                 {
  7.                         j=i+1;
  8.                         if(day[i]>day[j])
  9.                         {
  10.                                 p[i]=reminders[j];
  11.                                 p[j]=reminders[i];
  12.                         }
  13.                
  14.                 }
  15.                 ch=j;
  16.         }
复制代码


      上面的代码在 len > 1 的时候会进入死循环,整体用下面的代码替换就可以了:

  1.         int tx                                                              ;
  2.         char * px                                                           ;
  3.         for(i = 1 ; i < len ; i ++) {
  4.                 for(j = i ; j > 0 && day[j] < day[j - 1] ; j --)  {
  5.                         tx = day[j]                                         ;
  6.                         day[j] = day[j - 1]                                 ;
  7.                         day[j - 1] = tx                                     ;
  8.                         px = p[j]                                           ;
  9.                         p[j] = p[j - 1]                                     ;
  10.                         p[j - 1] = px                                       ;
  11.                 }
  12.         }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-12 22:43:51 | 显示全部楼层
jackz007 发表于 2019-8-12 22:29
问题出在你的排序循环上了,就是下面这块代码:

感谢。排序问题可以解决了,但是那个for循环好像还有问题。
假设输入数字1234,(我用了sprint函数,应该最后的结果只保留2位的),结果整个数字都保留在day_str数组里了,可能还会超出数组边界。好奇怪啊。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-12 23:00:10 | 显示全部楼层
        继续整体优化,谨供楼主参考:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. #define MAX_REMIND 50
  5. #define MSG_LEN 60

  6. int main(void)
  7. {
  8.         char reminders[MAX_REMIND][MSG_LEN + 3]                             ;
  9.         char * p[MAX_REMIND] , * px                                         ;
  10.         int day[MAX_REMIND] = {0} , i , j , len                             ;
  11.         int tx                                                              ;

  12.         for(len = 0 , j = 0 ; j < MAX_REMIND ; j ++ , len ++) {
  13.                 printf("Enter the day and reminder : ")                     ;
  14.                 fgets(reminders[j] , MSG_LEN + 2 , stdin)                   ;
  15.                 reminders[j][strlen(reminders[j]) - 1] = '\0'               ;
  16.                 sscanf(reminders[j] , "%d" , & day[j])                      ;
  17.                 if (day[j] == 0) break                                      ;
  18.                 p[j] = reminders[j]                                         ;
  19.         }
  20.         for(i = 1 ; i < len ; i ++) {
  21.                 for(j = i ; j > 0 && day[j] < day[j - 1] ; j --) {
  22.                         tx = day[j]                                         ;
  23.                         day[j] = day[j - 1]                                 ;
  24.                         day[j - 1] = tx                                     ;
  25.                         px = p[j]                                           ;
  26.                         p[j] = p[j - 1]                                     ;
  27.                         p[j - 1] = px                                       ;
  28.                 }
  29.         }
  30.         for(i = 0 ; i < len ; i ++) printf("%s\n" , p[i])                   ;
  31. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-12 23:05:09 | 显示全部楼层
jiuyuan 发表于 2019-8-12 22:43
感谢。排序问题可以解决了,但是那个for循环好像还有问题。
假设输入数字1234,(我用了sprint函数,应 ...

     难道你希望输入 1234  让 day[j] = 12 ?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-12 23:11:21 | 显示全部楼层
jackz007 发表于 2019-8-12 23:00
继续整体优化,谨供楼主参考:

你的代码很精简,但是对于新手来说读起来有点困难,我慢慢看吧。
还有一个问题没解决,我首先要输入一个数字,如果大于两位数,我只在reminders里保留前两个字符。我写的for循环里sprintf(day_str,"%2d",day[j])有什么问题吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-12 23:14:00 | 显示全部楼层
jackz007 发表于 2019-8-12 23:05
难道你希望输入 1234  让 day[j] = 12 ?

不是,day[j]肯定存的是int 的1234,我想把12转化成字符存到day_str[3]里
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-12 23:22:13 | 显示全部楼层
本帖最后由 jackz007 于 2019-8-12 23:33 编辑
jiuyuan 发表于 2019-8-12 23:11
你的代码很精简,但是对于新手来说读起来有点困难,我慢慢看吧。
还有一个问题没解决,我首先要输入一个 ...


      如果 day[j] = 1234 的话,sprintf(day_str,"%2d",day[j]),day_str 的内容一定是 '1234' ,在这种情况下,域宽指示符 2 失效,因为要显示的数据位数实际上已经超过了 2 位。'%2d' 只会在要显示的数据不超过 2 位数的时候才有意义,如果超出就会失效。

      如果你一定好取前 2 位的话,这么操作:
  1.         tx = day[j]               ;
  2.         while(tx > 99) tx /= 10   ;
  3.         sprintf(day_str,"%2d",tx) ;
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-12 23:29:34 | 显示全部楼层
jackz007 发表于 2019-8-12 23:22
如果 day[j] = 1234 的话,sprintf(day_str,"%2d",day[j]),day_str 的内容一定是 '1234' ,在这 ...

好的,我知道了,我再想想办法存字符时只保留两位。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-12 23:32:02 | 显示全部楼层
jiuyuan 发表于 2019-8-12 23:29
好的,我知道了,我再想想办法存字符时只保留两位。

    我已经为你想出了办法,还是在 11 楼
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-12 23:44:30 | 显示全部楼层
jackz007 发表于 2019-8-12 23:32
我已经为你想出了办法,还是在 11 楼

老哥,我要吐血了。
没看到你这个方法前,我打算用前几天(你刚帮我解决了一点疑惑)刚学的那个字节表示的方法提取数字,再转换ASCII。
你的这个方法我用了,它不生效啊。看起来时day[j]的前两位数存到tx,再把tx存到day_str,但是我还是把day[j],所有位数的存到reminders里了。我有点晕。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-12 23:53:57 | 显示全部楼层
jiuyuan 发表于 2019-8-12 23:44
老哥,我要吐血了。
没看到你这个方法前,我打算用前几天(你刚帮我解决了一点疑惑)刚学的那个字节表示 ...

      把你代码里的这一块代码:
  1.                 sprintf(day_str,"%2d",day[j]);
  2.                 i=1;
  3.                 msg_str[0]=' ';
  4.                 while((ch=getchar())!='\n')
  5.                 {
  6.                         msg_str[i++]=ch;
  7.                         
  8.                 }
  9.                 msg_str[i]='\0';
  10.                 strcat(strcpy(reminders[j],day_str),msg_str);
复制代码


      整体用下面的代码替换,我就不相信不起效!

  1.                 while(day[j] > 99) day[j] /= 10                    ;
  2.                 sprintf(day_str , "%2d", day[j])                   ;
  3.                 i = 0                                              ;
  4.                 msg_str[i ++] = ' '                                ;
  5.                 while((ch = getchar()) != '\n') msg_str[i ++] = ch ;
  6.                 msg_str[i]='\0'                                    ;
  7.                 strcat(strcpy(reminders[j] , day_str) , msg_str)   ;
复制代码

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-13 00:04:03 | 显示全部楼层
jackz007 发表于 2019-8-12 23:53
把你代码里的这一块代码:

老哥,还是有问题啊。我全用的你的代码,排序部分也是。
我输入1234,然后输出是“?”和后面的字符。
你看看我提取int字节里的值,然后转化成字符,输出也是最前面是“?”。我也重写了那个排序部分,现在我写的这个和全用你的代码问题一样了。
  1. #include <stdio.h>
  2. #include <string.h>
  3. #define MAX_REMIND 50
  4. #define MSG_LEN 60

  5. typedef unsigned char * pointer;

  6. int main()
  7. {
  8.         char reminders[MAX_REMIND][MSG_LEN+3]={0};
  9.         char day_str[3]={0},msg_str[MSG_LEN+1];
  10.         int day[MAX_REMIND]={0},i,j=0,num_remind=0,ch,len=0;
  11.         char *p[MAX_REMIND];
  12.        
  13.        
  14.         for(;;)
  15.         {
  16.                 printf("Enter the day and reminder:");
  17.                 scanf("%d",&day[j]);
  18.                 unsigned char *q;
  19.                 q=(pointer)&day[j];
  20.                 if(day[j]==0)
  21.                 break;
  22.                 //sprintf(day_str,"%2d",day[j]);
  23.                 day_str[0]=(*q++)+30;
  24.                 day_str[1]=(*q)+30;
  25.                 day_str[2]='\0';
  26.                 i=1;
  27.                 msg_str[0]=' ';
  28.                 while((ch=getchar())!='\n')
  29.                 {
  30.                         msg_str[i++]=ch;
  31.                        
  32.                 }
  33.                 msg_str[i]='\0';
  34.                 strcat(strcpy(reminders[j],day_str),msg_str);
  35.                 j++;       
  36.         }
  37.        
  38.         for(i=0;i<j;i++)
  39.         {
  40.                 p[i]=reminders[i];
  41.                 len++;
  42.         }
  43.         ch=len-1;
  44.         while(ch>=0)
  45.         {
  46.                 j=-1;
  47.                 for(i=1;i<=ch;i++)
  48.                 {
  49.                        
  50.                         if(day[i-1]>day[i])
  51.                         {
  52.                                 j=i-1;
  53.                                 p[i]=reminders[j];
  54.                                 p[j]=reminders[i];
  55.                         }
  56.                
  57.                 }
  58.                 ch=j;
  59.         }
  60.        
  61.         for(i=0;i<len;i++)
  62.         printf("%s\n",p[i]);
  63.        
  64.         return 0;
  65.        
  66. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-13 00:05:39 | 显示全部楼层
jiuyuan 发表于 2019-8-13 00:04
老哥,还是有问题啊。我全用的你的代码,排序部分也是。
我输入1234,然后输出是“?”和后面的字符。
...

30那个地方应该是48,
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-13 00:12:33 | 显示全部楼层
jackz007 发表于 2019-8-12 23:53
把你代码里的这一块代码:

我突然想到,我输入的是十进制,计算机内部保存为二进制。然后我再直接提取int字节的值,又转换成十进制,好像不是我想要的十进制的值。比如1234,提取第一个字节的值应该不是1.
好心累,明天再看吧,老哥早点休息。我也要睡了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-8-13 00:18:51 | 显示全部楼层    本楼为最佳答案   
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. #define MAX_REMIND 50
  5. #define MSG_LEN 60

  6. int main(void)
  7. {
  8.         char reminders[MAX_REMIND][MSG_LEN + 3]                             ;
  9.         char day_str[3] , msg_str[MSG_LEN + 1]                              ;
  10.         int day[MAX_REMIND]={0} , i , j = 0 , num_remind = 0 , ch , len = 0 ;
  11.         int tx                                                              ;
  12.         char * p[MAX_REMIND] , * px                                         ;

  13.         for(;;) {
  14.                 printf("Enter the day and reminder : ")                     ;
  15.                 scanf("%d" , & day[j])                                      ;
  16.                 if(day[j] == 0) break                                       ;
  17.                 while(day[j] > 99) day[j] /= 10                             ;
  18.                 sprintf(day_str , "%2d" , day[j])                           ;
  19.                 i = 0                                                       ;
  20.                 msg_str[i] = '\0'                                           ;
  21.                 while((ch = getchar()) != '\n') msg_str[i ++] = ch          ;
  22.                 msg_str[i]= '\0'                                            ;
  23.                 strcat(strcpy(reminders[j] , day_str) , msg_str)            ;
  24.                 j ++                                                        ;        
  25.         }
  26.         for(i = 0 ; i < j ; i ++) {
  27.                 p[i] = reminders[i]                                         ;
  28.                 len ++                                                      ;
  29.         }
  30.         for(i = 1 ; i < len ; i ++) {
  31.                 for(j = i ; j > 0 && day[j] < day[j - 1] ; j --) {
  32.                         tx = day[j]                                         ;
  33.                         day[j] = day[j - 1]                                 ;
  34.                         day[j - 1] = tx                                     ;
  35.                         px = p[j]                                           ;
  36.                         p[j] = p[j - 1]                                     ;
  37.                         p[j - 1] = px                                       ;
  38.                 }
  39.         }
  40.         for(i = 0 ; i < len ; i ++) printf("%s\n" , p[i])                   ;
  41. }
复制代码


      你是怎么弄的,看看我这里的运行实况:

  1. C:\Bin>g++ -o x2 x2.c

  2. C:\Bin>x2
  3. Enter the day and reminder : 13 1234
  4. Enter the day and reminder : 12 1234
  5. Enter the day and reminder : 11 1234
  6. Enter the day and reminder : 1588 1234
  7. Enter the day and reminder : 1789 1234
  8. Enter the day and reminder : 19870 1234
  9. Enter the day and reminder : 291876 1234
  10. Enter the day and reminder : 5 1234
  11. Enter the day and reminder : 2 1234
  12. Enter the day and reminder : 0
  13. 2 1234
  14. 5 1234
  15. 11 1234
  16. 12 1234
  17. 13 1234
  18. 15 1234
  19. 17 1234
  20. 19 1234
  21. 29 1234

  22. C:\Bin>
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-8-13 07:11:04 | 显示全部楼层
本帖最后由 jiuyuan 于 2019-8-13 07:12 编辑
jackz007 发表于 2019-8-13 00:18
你是怎么弄的,看看我这里的运行实况:


这。。。
我刚才复制了你的代码,又运行了一下,结果是乱码。我用的DevC++这个编译器。我再研究一下

                               
登录/注册后可看大图
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-1 16:02

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表