鱼C论坛

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

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

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

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

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

x
#include <stdio.h>
#include <string.h>
#define MAX_REMIND 50
#define MSG_LEN 60


int main()
{
        char reminders[MAX_REMIND][MSG_LEN+3];
        char day_str[3],msg_str[MSG_LEN+1];
        int day[MAX_REMIND]={0},i,j=0,num_remind=0,ch,len=0;
        char *p[MAX_REMIND];
        
/*
        for(;;)
        {
                printf("Enter the day and reminder:");
                scanf("%d",&day[j]);
                if(day[j]==0)
                break;
                sprintf(day_str,"%2d",day[j]);
                i=1;
                msg_str[0]=' ';
                while((ch=getchar())!='\n')
                {
                        msg_str[i++]=ch;
                        
                }
                msg_str[i]='\0';
                strcat(strcpy(reminders[j],day_str),msg_str);
                j++;        
        }

*/
        
        for(i=0;i<j;i++)
        {
                p[i]=reminders[i];
                len++;
        }
        ch=len-1;
        while(ch>=0)
        {
                j=-1;
                for(i=0;i<=ch-1;i++)
                {
                        j=i+1;
                        if(day[i]>day[j])
                        {
                                p[i]=reminders[j];
                                p[j]=reminders[i];
                        }
                
                }
                ch=j;
        }
        
        for(i=0;i<len;i++)
        printf("%s\n",p[i]);
        
        return 0;
        
}

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

#define MAX_REMIND 50
#define MSG_LEN 60

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

        for(;;) {
                printf("Enter the day and reminder : ")                     ;
                scanf("%d" , & day[j])                                      ;
                if(day[j] == 0) break                                       ;
                while(day[j] > 99) day[j] /= 10                             ;
                sprintf(day_str , "%2d" , day[j])                           ;
                i = 0                                                       ;
                msg_str[i] = '\0'                                           ;
                while((ch = getchar()) != '\n') msg_str[i ++] = ch          ;
                msg_str[i]= '\0'                                            ;
                strcat(strcpy(reminders[j] , day_str) , msg_str)            ;
                j ++                                                        ;        
        }
        for(i = 0 ; i < j ; i ++) {
                p[i] = reminders[i]                                         ;
                len ++                                                      ;
        }
        for(i = 1 ; i < len ; i ++) {
                for(j = i ; j > 0 && day[j] < day[j - 1] ; j --) {
                        tx = day[j]                                         ;
                        day[j] = day[j - 1]                                 ;
                        day[j - 1] = tx                                     ;
                        px = p[j]                                           ;
                        p[j] = p[j - 1]                                     ;
                        p[j - 1] = px                                       ;
                }
        }
        for(i = 0 ; i < len ; i ++) printf("%s\n" , p[i])                   ;
}

      你是怎么弄的,看看我这里的运行实况:
C:\Bin>g++ -o x2 x2.c

C:\Bin>x2
Enter the day and reminder : 13 1234
Enter the day and reminder : 12 1234
Enter the day and reminder : 11 1234
Enter the day and reminder : 1588 1234
Enter the day and reminder : 1789 1234
Enter the day and reminder : 19870 1234
Enter the day and reminder : 291876 1234
Enter the day and reminder : 5 1234
Enter the day and reminder : 2 1234
Enter the day and reminder : 0
 2 1234
 5 1234
11 1234
12 1234
13 1234
15 1234
17 1234
19 1234
29 1234

C:\Bin>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

使用道具 举报

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

比如 输入:“12 1234(回车)0”,这样可以退出循环
       输入:“ 12 1234(回车)13 1234(回车)0”,退不出循环
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

我想要输入多个信息,保存再二维数组里,可以退出这个循环。问题是退不出来
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

    问题出在你的排序循环上了,就是下面这块代码:
        ch=len-1;
        while(ch>=0)
        {
                j=-1;
                for(i=0;i<=ch-1;i++)
                {
                        j=i+1;
                        if(day[i]>day[j])
                        {
                                p[i]=reminders[j];
                                p[j]=reminders[i];
                        }
                
                }
                ch=j;
        }

      上面的代码在 len > 1 的时候会进入死循环,整体用下面的代码替换就可以了:
        int tx                                                              ;
        char * px                                                           ;
        for(i = 1 ; i < len ; i ++) {
                for(j = i ; j > 0 && day[j] < day[j - 1] ; j --)  {
                        tx = day[j]                                         ;
                        day[j] = day[j - 1]                                 ;
                        day[j - 1] = tx                                     ;
                        px = p[j]                                           ;
                        p[j] = p[j - 1]                                     ;
                        p[j - 1] = px                                       ;
                }
        }
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

#define MAX_REMIND 50
#define MSG_LEN 60

int main(void)
{
        char reminders[MAX_REMIND][MSG_LEN + 3]                             ;
        char * p[MAX_REMIND] , * px                                         ;
        int day[MAX_REMIND] = {0} , i , j , len                             ;
        int tx                                                              ;

        for(len = 0 , j = 0 ; j < MAX_REMIND ; j ++ , len ++) {
                printf("Enter the day and reminder : ")                     ;
                fgets(reminders[j] , MSG_LEN + 2 , stdin)                   ;
                reminders[j][strlen(reminders[j]) - 1] = '\0'               ;
                sscanf(reminders[j] , "%d" , & day[j])                      ;
                if (day[j] == 0) break                                      ;
                p[j] = reminders[j]                                         ;
        }
        for(i = 1 ; i < len ; i ++) {
                for(j = i ; j > 0 && day[j] < day[j - 1] ; j --) {
                        tx = day[j]                                         ;
                        day[j] = day[j - 1]                                 ;
                        day[j - 1] = tx                                     ;
                        px = p[j]                                           ;
                        p[j] = p[j - 1]                                     ;
                        p[j - 1] = px                                       ;
                }
        }
        for(i = 0 ; i < len ; i ++) printf("%s\n" , p[i])                   ;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

     难道你希望输入 1234  让 day[j] = 12 ?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

你的代码很精简,但是对于新手来说读起来有点困难,我慢慢看吧。
还有一个问题没解决,我首先要输入一个数字,如果大于两位数,我只在reminders里保留前两个字符。我写的for循环里sprintf(day_str,"%2d",day[j])有什么问题吗?
想知道小甲鱼最近在做啥?请访问 -> 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]里
想知道小甲鱼最近在做啥?请访问 -> 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 位的话,这么操作:
        tx = day[j]               ;
        while(tx > 99) tx /= 10   ;
        sprintf(day_str,"%2d",tx) ;
想知道小甲鱼最近在做啥?请访问 -> 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' ,在这 ...

好的,我知道了,我再想想办法存字符时只保留两位。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

    我已经为你想出了办法,还是在 11 楼
想知道小甲鱼最近在做啥?请访问 -> 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里了。我有点晕。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

      把你代码里的这一块代码:
                sprintf(day_str,"%2d",day[j]);
                i=1;
                msg_str[0]=' ';
                while((ch=getchar())!='\n')
                {
                        msg_str[i++]=ch;
                        
                }
                msg_str[i]='\0';
                strcat(strcpy(reminders[j],day_str),msg_str);

      整体用下面的代码替换,我就不相信不起效!
                while(day[j] > 99) day[j] /= 10                    ;
                sprintf(day_str , "%2d", day[j])                   ;
                i = 0                                              ;
                msg_str[i ++] = ' '                                ;
                while((ch = getchar()) != '\n') msg_str[i ++] = ch ;
                msg_str[i]='\0'                                    ;
                strcat(strcpy(reminders[j] , day_str) , msg_str)   ;
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

typedef unsigned char * pointer;

int main()
{
        char reminders[MAX_REMIND][MSG_LEN+3]={0};
        char day_str[3]={0},msg_str[MSG_LEN+1];
        int day[MAX_REMIND]={0},i,j=0,num_remind=0,ch,len=0;
        char *p[MAX_REMIND];
        
        
        for(;;)
        {
                printf("Enter the day and reminder:");
                scanf("%d",&day[j]);
                unsigned char *q;
                q=(pointer)&day[j];
                if(day[j]==0)
                break;
                //sprintf(day_str,"%2d",day[j]);
                day_str[0]=(*q++)+30;
                day_str[1]=(*q)+30;
                day_str[2]='\0';
                i=1;
                msg_str[0]=' ';
                while((ch=getchar())!='\n')
                {
                        msg_str[i++]=ch;
                        
                }
                msg_str[i]='\0';
                strcat(strcpy(reminders[j],day_str),msg_str);
                j++;        
        }
        
        for(i=0;i<j;i++)
        {
                p[i]=reminders[i];
                len++;
        }
        ch=len-1;
        while(ch>=0)
        {
                j=-1;
                for(i=1;i<=ch;i++)
                {
                        
                        if(day[i-1]>day[i])
                        {
                                j=i-1;
                                p[i]=reminders[j];
                                p[j]=reminders[i];
                        }
                
                }
                ch=j;
        }
        
        for(i=0;i<len;i++)
        printf("%s\n",p[i]);
        
        return 0;
        
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

30那个地方应该是48,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

#define MAX_REMIND 50
#define MSG_LEN 60

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

        for(;;) {
                printf("Enter the day and reminder : ")                     ;
                scanf("%d" , & day[j])                                      ;
                if(day[j] == 0) break                                       ;
                while(day[j] > 99) day[j] /= 10                             ;
                sprintf(day_str , "%2d" , day[j])                           ;
                i = 0                                                       ;
                msg_str[i] = '\0'                                           ;
                while((ch = getchar()) != '\n') msg_str[i ++] = ch          ;
                msg_str[i]= '\0'                                            ;
                strcat(strcpy(reminders[j] , day_str) , msg_str)            ;
                j ++                                                        ;        
        }
        for(i = 0 ; i < j ; i ++) {
                p[i] = reminders[i]                                         ;
                len ++                                                      ;
        }
        for(i = 1 ; i < len ; i ++) {
                for(j = i ; j > 0 && day[j] < day[j - 1] ; j --) {
                        tx = day[j]                                         ;
                        day[j] = day[j - 1]                                 ;
                        day[j - 1] = tx                                     ;
                        px = p[j]                                           ;
                        p[j] = p[j - 1]                                     ;
                        p[j - 1] = px                                       ;
                }
        }
        for(i = 0 ; i < len ; i ++) printf("%s\n" , p[i])                   ;
}

      你是怎么弄的,看看我这里的运行实况:
C:\Bin>g++ -o x2 x2.c

C:\Bin>x2
Enter the day and reminder : 13 1234
Enter the day and reminder : 12 1234
Enter the day and reminder : 11 1234
Enter the day and reminder : 1588 1234
Enter the day and reminder : 1789 1234
Enter the day and reminder : 19870 1234
Enter the day and reminder : 291876 1234
Enter the day and reminder : 5 1234
Enter the day and reminder : 2 1234
Enter the day and reminder : 0
 2 1234
 5 1234
11 1234
12 1234
13 1234
15 1234
17 1234
19 1234
29 1234

C:\Bin>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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


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

                               
登录/注册后可看大图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-10-4 03:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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