标题:如何读取一个文件把文件每行内容赋值给一个结构数组元素
只看楼主
khaz
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:130
专家分:188
注 册:2011-4-21
结帖率:77.78%
已结贴  问题点数:20 回复次数:10 
如何读取一个文件把文件每行内容赋值给一个结构数组元素
例如:
结构为:
struct emp{
char name[20];
long age;
char phone[12];
}
文件第一列为名字 第二列为年龄 第三列为手机号
emp.txt:
fred|30|18677442345
barney|29|13766554321
jq|36|18977890987
我想通过编写C程序,把这个文件的内容循环读取到一个结构数组去,每次读取一行,遇到文件尾结束读取,每个数组元素对应为一个人。
如何编写,请教了。


[ 本帖最后由 khaz 于 2011-4-22 22:51 编辑 ]
搜索更多相关主题的帖子: 手机号 名字 元素 
2011-04-22 22:46
voidx
Rank: 12Rank: 12Rank: 12
来 自:邯郸
等 级:火箭侠
帖 子:1250
专家分:3538
注 册:2011-4-7
得分:0 
如此:

FILE * fp = fopen("path_to_your_file", "r");
struct emp a;
fscanf(fp, " %s %d %s", a.name, &a.age, a.phone);
2011-04-22 22:53
khaz
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:130
专家分:188
注 册:2011-4-21
得分:0 
谢谢,我是想按行读入到数组里,我就假定emp.txt只有3行了,所以行数下面的程序写死了,看看我这样写可以吗?报错信息为:Segmentation fault

错在哪?
程序代码:
#include<stdio.h>
#include<unistd.h>
struct emp{
        char name[20];
        long age;
        char phone[12];
};

int main(){
        int i;
        char *str;
        FILE * fp = fopen("emp.txt", "r");
        struct emp a[3];
        while(fgets(str,50,fp)!=NULL){
                for(i=0;i<3;i++){
                sscanf(str, "%s|%ld|%s", a[i].name, &a[i].age, a[i].phone);
                }
        }
}


[ 本帖最后由 khaz 于 2011-4-23 10:05 编辑 ]
2011-04-23 09:42
voidx
Rank: 12Rank: 12Rank: 12
来 自:邯郸
等 级:火箭侠
帖 子:1250
专家分:3538
注 册:2011-4-7
得分:5 
首先,你又不给 str 分配空间,让人家往哪读?
其次,你的文件里按这样的格式来写 fred|30|18677442345,fgets 后 str == "fred|30|18677442345"
在 sscanf 的时候 "fred|30|18677442345" 会被当作一个字符串全部读到 a[i].name 里去。
把 '|' 换成 ' '
2011-04-23 10:08
逐渐学习
Rank: 6Rank: 6
等 级:侠之大者
帖 子:113
专家分:454
注 册:2010-9-26
得分:12 
程序代码:
#include<stdio.h>
//#include<unistd.h>
struct emp{
        char name[20];
        long age;
        char phone[12];
};

int main(){
        int i;
        char str[50];
        FILE * fp = fopen("emp.txt", "r");
        struct emp a[3];
        i=0;
        while(fgets(str,50,fp)!=NULL){
                //for(i=0;i<3;i++){
                sscanf(str, "%[^|]|%ld|%s", a[i].name, &a[i].age, a[i].phone);
                //}
                i++;
        }
        return 0;
}
1、str应该指向具体地址,要么是数组,要么用malloc分配
2、fgets每次按一行读取,不是一次读取整个文件的
3、sscanf掩码注意集合[^|]代表读取到不为|的字符串,long用ld读取
收到的鲜花
  • voidx2011-04-23 10:13 送鲜花  2朵  

帮人《---》帮己
2011-04-23 10:09
ying8501
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:6
帖 子:1092
专家分:1446
注 册:2008-11-24
得分:3 
请问一下楼上:在sscanf()中,| 作为字符串的分隔符可以吗? 额,谢谢查到了。学习了。
又:
楼主的题目要求必须用sscanf()吗?需要改的地方挺多,楼主自己改改试试。
#include<stdio.h>
#include<unistd.h>
struct emp{
        char name[20];
        long age;
        char phone[12];
};

int main(){
        int i;
        char char* str;    //   -- 失控指针:没开辟空间,应该用 数组: char str[100];
        FILE * fp = fopen("emp.txt", "r");
        struct emp a[3];
        while(fgets(str,50,fp)!=NULL){   // --fgets()一次只能读一行不会直接读三行,
                for(i=0;i<3;i++){
                sscanf(str, "%s|%d|%s", a[i].name, &a[i].age, a[i].phone);  //在emp文件中,| 作为字符串的分隔符是不行的,应该用空格
                }
        }   //内循环每次都读到了一个数组里了
   
        return 0;
}

[ 本帖最后由 ying8501 于 2011-4-23 10:45 编辑 ]
2011-04-23 10:23
khaz
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:130
专家分:188
注 册:2011-4-21
得分:0 
谢谢 各位大虾的批评 我学习和考虑一下
2011-04-23 10:26
khaz
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:130
专家分:188
注 册:2011-4-21
得分:0 
感谢5楼,也要感谢voidx和6楼,再次提醒了空间分配的错误。
根据各位大虾的意见,我修改了一下,并增加了结果输出:
方法一:
[view@localhost c]$cat emp.txt
fred|30|18677442345
barney|29|13766554321
jq|36|18977890987

[view@localhost c]$cat 3.c
#include<stdio.h>
struct emp{
        char name[20];
        long age;
        char phone[12];
};

int main(){
        int i,ret;
        char str[50];
        FILE * fp = fopen("emp.txt", "r");
        struct emp a[3];
        i=0;
        while(fgets(str,50,fp)!=NULL){
                if((ret=sscanf(str, "%[^|]|%ld|%s", a[i].name, &a[i].age, a[i].phone))<3){
                fprintf(stderr,"sscanf() err!,ret=%d\n",ret);
                fclose(fp);
                exit(1);
        }
                i++;
        }
        for(i=0;i<3;i++){
        printf("emp%d name is %s,age is %ld,phone is %s\n",i,a[i].name,a[i].age,a[i].phone);
        }
        fclose(fp);
        return 0;
}


[view@localhost c]$cc -o 3 3.c
[view@localhost c]$./3
emp0 name is fred,age is 30,phone is 18677442345
emp1 name is barney,age is 29,phone is 13766554321
方法二:
[view@localhost c]$cat emp.txt
fred 30 18677442345
barney 29 13766554321
jq 36 18977890987
[view@localhost c]$cat 4.c
#include<stdio.h>
struct emp{
        char name[20];
        long age;
        char phone[12];
};

int main(){
        int i,ret;
        char *str=(char *)malloc(50);
        FILE * fp = fopen("emp.txt", "r");
        struct emp a[3];
        i=0;
        while(fgets(str,50,fp)!=NULL){
                if((ret=sscanf(str, "%s %ld %s", a[i].name, &a[i].age, a[i].phone))<3){
                fprintf(stderr,"sscanf() err!,ret=%d\n",ret);
                fclose(fp);
                exit(1);
        }
                i++;
        }
        for(i=0;i<3;i++){
        printf("emp%d name is %s,age is %ld,phone is %s\n",i,a[i].name,a[i].age,a[i].phone);
        }
        fclose(fp);
        return 0;
}


[view@localhost c]$cc -o 4 4.c
[view@localhost c]$./4
emp0 name is fred,age is 30,phone is 18677442345
emp1 name is barney,age is 29,phone is 13766554321
emp2 name is jq,age is 36,phone is 18977890987
程序虽然简单,但是实用性很强,工作中要用到。以前习惯了用shell处理文本,用C倒是第一次。

[ 本帖最后由 khaz 于 2011-4-23 11:08 编辑 ]
2011-04-23 10:51
khaz
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:130
专家分:188
注 册:2011-4-21
得分:0 
程序代码:
#include<stdio.h>
struct emp{
        char name[20];
        long age;
        char phone[12];
};

int main(){
        int i,ret,line,col;
        char str[50];
        FILE * f;
        FILE * fp = fopen("emp.txt", "r");
        f=popen("wc -l emp.txt|awk '{print $1}'","r");
        fscanf(f,"%d",&line);
        printf("line=%d\n",line);
        struct emp a[line];
        f=popen("awk -F'|' '{print NF}' emp.txt|sort -u","r");
        fscanf(f,"%d",&col);
        printf("col=%d\n",col);

        i=0;
        while(fgets(str,50,fp)!=NULL){
                if((ret=sscanf(str, "%[^|]|%ld|%s", a[i].name, &a[i].age, a[i].phone))<col){
                fprintf(stderr,"sscanf() err!,ret=%d\n",ret);
                fclose(fp);
                exit(1);
        }
                i++;
        }
        for(i=0;i<line;i++){
        printf("emp%d name is %s,age is %ld,phone is %s\n",i,a[i].name,a[i].age,a[i].phone);
        }
        fclose(fp);
        return 0;
}


我又改了一下,调用了shell去计算了文件行数和列数,虽然取列数有点多余,可毕竟是为了练手。而且用C计算有点麻烦,同事跟我说,C语言之父说过,C编程中有半打是用shell、perl等去处理的。我开始试图使用system函数,可是system函数返回值只是0,根据网上资料,我想取得shell的运行结果就用了popen,
程序执行结果为:
line=3
col=3
emp0 name is fred,age is 30,phone is 18677442345
emp1 name is barney,age is 29,phone is 13766554321
emp2 name is jq,age is 36,phone is 18977890987
2011-04-23 11:45
hytiantang
Rank: 1
等 级:新手上路
帖 子:10
专家分:2
注 册:2011-4-23
得分:0 
路过精彩!1
2011-04-23 11:55



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-337610-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.069979 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved