日本看板
广告位招租 详细信息请联系 jkanban@gmail.com キャンペン中!


 
标题: [C++] c语言弱问题 谢谢
  本主题由 admin 于 2008-6-4 17:54 分类 
雪娃
业余诗人
Rank: 2Rank: 2


UID 1252
精华 0
积分 409
帖子 105
威望 48
金钱 649
慈善捐款(日元) 0
阅读权限 30
注册 2008-2-26
 
发表于 2008-5-15 11:04  资料  个人空间  短消息  加为好友 
c语言弱问题 谢谢

我定义的结构体数组 ,
其中有一部分语句是把文本文件中每行(两个逗号分成三部分--结构体)的数据给一个数组元素,
结构体的大小是定了的
可是 比如中间的age[3],怎么也会把后面的addr也读入进来,输出显示的时候,居然是年龄连着后面的地址  然后地址还是地址的字符 我不是定义中限制大小了吗 以前遇到过这样的问题 解决了 但彻底想不起来了

哪位高手给看看

//データ用構造体定義
struct address{
        char name[20];
        char age[3];
        char addr[40];
};

//構造体型(最大9件)配列定義
struct address addr[9];




for(i=0;i<9;i++)
        {
               
                //行でデータを取得する
                fgets(str,100,fp);
                //文字列strの先頭から第1のカンマを探し、最初に見つかる
                p1=strchr(str,',');
                //ポインタの指定
                f=p1-&str[0];
                //構造体nameに文字列strを先頭からf文字コピーする(nameを作成)
                //printf("f=",f);
                strncpy(addr.name,&str[0],f);
                printf("\n%s\n",addr.name);
                //第2のカンマを探し続く
                p2=strchr(&str[f+1],',');
                m=p2-&str[0];
                //ageを作成
                strncpy(addr.age,&str[f+1],m-f-1);
                printf("%s\n",addr.age);
                //第3のカンマを探し続く
                p3=strchr(&str[m+1],'\n');
                n=p3-&str[0];
                //addrを作成
                strncpy(addr.addr,&str[m+1],n-m-1);
                printf("%s\n",addr.addr);

                printf("%s,%s,%s",&addr.name[0],&addr.age[0],&addr.addr[0]);
        }

最后这句打印出来就重复 而且特点是 年龄是两位数和以下就不重复 三位数就把地址部分也读进来了 但是是有时候 还不是所有的三位数年龄都重复

比如显示出来是

newname,234ssssssfff,sssffff

本应该是

newname,234,sssffff

也许说的有点不明白 但若能知道原因 请告诉我





歩いても、歩いても、人生はいつもちょっとだけ間に合わない
でも あきらめない
顶部
www.rakudoor.com 乐道 樂道 楽道 -- Ruby on Rails试验田
雪娃
业余诗人
Rank: 2Rank: 2


UID 1252
精华 0
积分 409
帖子 105
威望 48
金钱 649
慈善捐款(日元) 0
阅读权限 30
注册 2008-2-26
 
发表于 2008-5-15 11:18  资料  个人空间  短消息  加为好友 
//データを読み込む、データがテキストファイルから構造体の配列に入れる
        for(i=0;i<9;i++)
        {
                //新しい方法がない?
                //行でデータを取得する
                fgets(str,100,fp);
                //文字列strの先頭から第1のカンマを探し、最初に見つかる
                p1=strchr(str,',');
                //ポインタの指定
                f=p1-&str[0];
                //構造体nameに文字列strを先頭からf文字コピーする(nameを作成)
                //printf("f=",f);
                strncpy(addr.name,&str[0],f);
                printf("\n%s\n",addr.name);
                //第2のカンマを探し続く
                p2=strchr(&str[f+1],',');
                m=p2-&str[0];
                //ageを作成
                strncpy(addr.age,&str[f+1],m-f-1);
                printf("%s\n",addr.age);
                //第3のカンマを探し続く
                p3=strchr(&str[m+1],'\n');
                n=p3-&str[0];
                //addrを作成
                strncpy(addr.addr,&str[m+1],n-m-1);
                printf("%s\n",addr.addr);

                printf("%s,%s,%s",&addr.name[0],&addr.age[0],&addr.addr[0]);
        }
我在这部分就发现 是这部分里面 就发生问题了
最后这句显示的时候 就看出问题了

但是还不知道是怎么回事
上面字体斜 我没有设置 自动的  不好意思





歩いても、歩いても、人生はいつもちょっとだけ間に合わない
でも あきらめない
顶部
雪娃
业余诗人
Rank: 2Rank: 2


UID 1252
精华 0
积分 409
帖子 105
威望 48
金钱 649
慈善捐款(日元) 0
阅读权限 30
注册 2008-2-26
 
发表于 2008-5-15 11:19  资料  个人空间  短消息  加为好友 
是这个网页程序的问题?发言过了多少行 就斜了?别笑我





歩いても、歩いても、人生はいつもちょっとだけ間に合わない
でも あきらめない
顶部
Ken
风流才子
Rank: 4Rank: 4Rank: 4Rank: 4


UID 278
精华 0
积分 3526
帖子 1316
威望 54
金钱 4502
慈善捐款(日元) 300
阅读权限 100
注册 2007-7-28
 
发表于 2008-5-15 11:19  资料  个人空间  短消息  加为好友 
为什么不用strtok函数呢?

顶部
Ken
风流才子
Rank: 4Rank: 4Rank: 4Rank: 4


UID 278
精华 0
积分 3526
帖子 1316
威望 54
金钱 4502
慈善捐款(日元) 300
阅读权限 100
注册 2007-7-28
 
发表于 2008-5-15 11:22  资料  个人空间  短消息  加为好友 
原型:char *strtok(char *s, char *delim);
功能:分解字符串为一组字符串。s为要分解的字符串,delim为分隔符。
说明:首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。
返回值:从s开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。所有delim中包含的字符都会被滤掉,并将被滤掉的地方设为一处分割的节点。

顶部
雪娃
业余诗人
Rank: 2Rank: 2


UID 1252
精华 0
积分 409
帖子 105
威望 48
金钱 649
慈善捐款(日元) 0
阅读权限 30
注册 2008-2-26
 
发表于 2008-5-15 11:28  资料  个人空间  短消息  加为好友 
好 我也觉得我的方法太麻烦 试试这个 我不知道 太好了 谢谢





歩いても、歩いても、人生はいつもちょっとだけ間に合わない
でも あきらめない
顶部
雪娃
业余诗人
Rank: 2Rank: 2


UID 1252
精华 0
积分 409
帖子 105
威望 48
金钱 649
慈善捐款(日元) 0
阅读权限 30
注册 2008-2-26
 
发表于 2008-5-15 11:34  资料  个人空间  短消息  加为好友 
这个方法非常好 见笑了 我还没有弄完 但是知道该有函数的 看来来问问对了





歩いても、歩いても、人生はいつもちょっとだけ間に合わない
でも あきらめない
顶部
Ken
风流才子
Rank: 4Rank: 4Rank: 4Rank: 4


UID 278
精华 0
积分 3526
帖子 1316
威望 54
金钱 4502
慈善捐款(日元) 300
阅读权限 100
注册 2007-7-28
 
发表于 2008-5-15 13:11  资料  个人空间  短消息  加为好友 
弄出来就好。

顶部
雪娃
业余诗人
Rank: 2Rank: 2


UID 1252
精华 0
积分 409
帖子 105
威望 48
金钱 649
慈善捐款(日元) 0
阅读权限 30
注册 2008-2-26
 
发表于 2008-5-15 16:58  资料  个人空间  短消息  加为好友 
非常感谢
上午已经出来了
但是下午发现一个问题

如果分割的字符串只有使用的分隔符 怎么办啊
比如我要用","号分隔 但被分隔的字符串只有  ,,,
我想分割得到三个空白 就是没有数据 置空就可以

这个时候严重出错

像这样的字符串就没有问题
dafsa,dfdfg,fdsfsd





歩いても、歩いても、人生はいつもちょっとだけ間に合わない
でも あきらめない
顶部
Ken
风流才子
Rank: 4Rank: 4Rank: 4Rank: 4


UID 278
精华 0
积分 3526
帖子 1316
威望 54
金钱 4502
慈善捐款(日元) 300
阅读权限 100
注册 2007-7-28
 
发表于 2008-5-15 17:21  资料  个人空间  短消息  加为好友 
判断返回值是否为\0,\0就是空串。

顶部
雪娃
业余诗人
Rank: 2Rank: 2


UID 1252
精华 0
积分 409
帖子 105
威望 48
金钱 649
慈善捐款(日元) 0
阅读权限 30
注册 2008-2-26
 
发表于 2008-5-16 14:38  资料  个人空间  短消息  加为好友 
再问

谢谢管理员给挪 这里我 找了好几回 没有找到合适的 地方 笨 啊

Ken 按你的指示 已经改好

但再问你一下 还有一个小小的问题 就是比如这个函数最后读进来的字符串是带着最后的\n
我怎样能去掉这个回车呢
它已经被读到最后的元素里去了
在都有数据可读入的时候可以解决
但是若是空数据 和有数据的行共存的时候 我置空的元素就不带这个\n
我想把置空的元素 最后一个也带上这个\n
或者把读入的那个去掉
总之希望空数据和数据都一样格式显示


怎么办呢





歩いても、歩いても、人生はいつもちょっとだけ間に合わない
でも あきらめない
顶部
Ken
风流才子
Rank: 4Rank: 4Rank: 4Rank: 4


UID 278
精华 0
积分 3526
帖子 1316
威望 54
金钱 4502
慈善捐款(日元) 300
阅读权限 100
注册 2007-7-28
 
发表于 2008-5-16 14:58  资料  个人空间  短消息  加为好友 
不好意思,没听明白...
\n是换行符,\0是字符串终止符,这两个不冲突啊。空数据行后边应该也有换行符啊,“置空的元素就不带这个\n”这是什么情况?

顶部
雪娃
业余诗人
Rank: 2Rank: 2


UID 1252
精华 0
积分 409
帖子 105
威望 48
金钱 649
慈善捐款(日元) 0
阅读权限 30
注册 2008-2-26
 
发表于 2008-5-16 15:11  资料  个人空间  短消息  加为好友 
continue

fgets(str,100,fp);                       
                p1= strtok( str, ",");
                if(p1!=NULL){
                strcpy(addr.name,p1);
                p1=strtok(NULL,",");
                }
               
                //データがない行、データを作成
                if(p1==NULL)
                {        addr.name[21]=NULL;                       
                        addr.age[4]=NULL;                       
                        addr.addr[41]=NULL;       
                //データがある行        、データを作成       
                }else{
                        strcpy(addr.age,p1);
                        p1=strtok(NULL,",");                       
                        strcpy(addr.addr,p1);
                }
               



        //データの表示
        for(i=0;i<9;i++){
                if(addr.name==NULL){
                        printf("%d\n",i+1);
                }
                else{
                        printf("%d       %-21s  %3s    %s\n",i+1,addr.name,addr.age,addr.addr);                 
                }
        }


在数据显示的时候
显示出来的 本来应该是一行一行挨着的
现在显示出来的是每行数据间有一个空行

而我执行了这句之后

        //ファイルに書き込む
        for(i=0;i<9;i++){
                fprintf(fp,"%s,%s,%s\n",addr.name,addr.age,addr.addr);
        }

原来的数据来源的文本文件被写入

再打开
就变成每行中间带一个空行的了

原来是没有的


应该是在数据读入那里出了问题

明白了吗 谢谢 这么麻烦 的事





歩いても、歩いても、人生はいつもちょっとだけ間に合わない
でも あきらめない
顶部
Ken
风流才子
Rank: 4Rank: 4Rank: 4Rank: 4


UID 278
精华 0
积分 3526
帖子 1316
威望 54
金钱 4502
慈善捐款(日元) 300
阅读权限 100
注册 2007-7-28
 
发表于 2008-5-16 15:29  资料  个人空间  短消息  加为好友 


QUOTE:
        //データの表示
        for(i=0;i<9;i++){
                if(addr.name==NULL){
                        printf("%d\n",i+1);
                }
                else{
                        printf("%d       %-21s  %3s    %s\n",i+1,addr.name,addr.age,addr.addr);                 
                }
        }



QUOTE:
        //ファイルに書き込む
        for(i=0;i<9;i++){
                fprintf(fp,"%s,%s,%s\n",addr.name,addr.age,addr.addr);
        }

空行是你自己加的...
原来的数据在最后一个字段(addr.addr)后边已经有换行了,有多加了一个,所以空了一行吧...

顶部
雪娃
业余诗人
Rank: 2Rank: 2


UID 1252
精华 0
积分 409
帖子 105
威望 48
金钱 649
慈善捐款(日元) 0
阅读权限 30
注册 2008-2-26
 
发表于 2008-5-16 17:02  资料  个人空间  短消息  加为好友 
应该是这么回事 总之是我自己没有搞清楚 应该修改没有问题
下午没有时间了
但已经知道可以弄好了


十分感谢 ken





歩いても、歩いても、人生はいつもちょっとだけ間に合わない
でも あきらめない
顶部
 



当前时区 GMT+9, 现在时间是 2008-7-9 10:51

    本论坛支付平台由支付宝提供
携手打造安全诚信的交易社区 Powered by Discuz! 5.5.0  © 2001-2007 Comsenz Inc.
清除 Cookies - 联系我们 - 日本看板 - Archiver