【新手求教~!】还是关于文本读取的问题~~

aabcg129 2017-11-17 10:49:48
莫名昨天的帖子被“404”了。。。。所以问题还是没有得到解决~
有下面的这一张txt文件,要用c编写程序来读取~
_____________________________________________________________________________
Name Age Sex Tel Address
-------------------------------------------------------------------------------------------------------------------------------------
张卫健 20 男 154 地球
PDD 30 男 510 火星
yfyf 40 男 608 水星
路发儿 50 女 603 Canada
张三 60 男 130 China
王老五 57 女 151 仙女座
Mr.Smith 55 男 243 America
王思聪 32 男 604 Australia
一刀水 41 女 620 南昌路
好愁人 42 男 330 北京人民公园
-------------------------------------------------------------------------------------------------------------------------------------
// txt文档要随时更新,所以得有一个通用的代码,不能存储成数组~~条件:
1.c语言读取。2.每次读取时,例如输入name,再输入1/2/3....显示第对应第几行的名字,输入Age....再输入1/2/3....显示对应第几行的年龄。
做了快一周了,还是没法做出来,刚学c语言,对这种复杂的还没学会如何去做。好悲伤....
...全文
565 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2017-11-17
  • 打赏
  • 举报
回复
仅供参考:
//NAME: essaie bla bla
//DIMENSION: 8
//DATA
//1  14  15
//2  11  10
//3  6   4
//4  7   13
//5  9   21
//6  19  3
//7  1   5
//8  8   8
//EOF
//
// 文本文件中可能还含有其他内容,但是需要用到的内容即以上

//比如data.txt:
//NAME: essaie bla bla
//其它内容
//DIMENSION: 8
//其它内容
//DATA
//其它内容
//1  14  15
//其它内容
//2  11  10
//其它内容
//3  6   4
//其它内容
//4  7   13
//其它内容
//5  9   21
//其它内容
//6  19  3
//其它内容
//7  1   5
//其它内容
//8  8   8
//其它内容
//EOF

// 目标是要获取NAME后字串,DIMENSION后数值,以及DATA以下的数值
// 其中NAME就是随便个字句,DIMENSION是城市数量,DATA以下是城市编号,X坐标,Y坐标
// 所有的这些将赋值给一个事先定义好的结构
#include <stdio.h>
#include <string.h>
#define MAXCPL   80   //每行最大字符数
#define MAXCITY  100  //每组数据中DATA最多项数,DIMENSION的最大值
#define MAXNAMEL 32   //NAME最大长度
struct S {
    char NAME[MAXNAMEL+1];
    int  DIMENSION;
    struct D {
        int NO;
        int X;
        int Y;
    } DATA[MAXCITY];
} s;
FILE *f;
int st,n,i;
char ln[MAXCPL];
int main() {
    f=fopen("data.txt","r");
    if (NULL==f) {
        printf("Can not open file data.txt!\n");
        return 1;
    }
    st=0;
    n=0;
    while (1) {
        if (NULL==fgets(ln,MAXCPL,f)) break;
        if (st==0) {
            if (1==sscanf(ln,"NAME: %31[^\n]",s.NAME)) st=1;
        } else if (st==1) {
            if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;
        } else if (st==2) {
            if (0==strcmp(ln,"DATA\n")) st=3;
        } else if (st==3) {
            if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {
                n++;
                if (n>=MAXCITY || n>=s.DIMENSION) break;
            }
        }
    }
    fclose(f);
    printf("s.NAME=[%s]\n",s.NAME);
    printf("s.DIMENSION=%d\n",s.DIMENSION);
    for (i=0;i<n;i++) {
        printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);
    }
    return 0;
}
//s.NAME=[essaie bla bla]
//s.DIMENSION=8
//s.DATA[0].NO,X,Y=1,14,15
//s.DATA[1].NO,X,Y=2,11,10
//s.DATA[2].NO,X,Y=3,6,4
//s.DATA[3].NO,X,Y=4,7,13
//s.DATA[4].NO,X,Y=5,9,21
//s.DATA[5].NO,X,Y=6,19,3
//s.DATA[6].NO,X,Y=7,1,5
//s.DATA[7].NO,X,Y=8,8,8

aabcg129 2017-11-17
  • 打赏
  • 举报
回复
引用 9 楼 hongwenjun 的回复:
#include <stdio.h>
#include <string.h>

int main()
{
    FILE* pFile;
    char* pch;
    char str [255] = {0};

    pFile = fopen("tel.csv" , "r");
    if (pFile == NULL) {
        perror("Error opening file");
        return -1;
    }
    fgets(str , 255 , pFile);
    while (! feof(pFile)) {
        pch = strtok(str, ",\n");
        while (pch != NULL) {
            printf("%s\t", pch);
            pch = strtok(NULL, ",\n");
        }
        printf("\n");
        fgets(str , 255 , pFile);  // 这样写法 解决BUG,不会输出最后一行的名字

    }
    fclose(pFile);
    return 0;
}
/* 输出结果
姓名    办电    宅电    手机    虚拟网
卢小珍  34521111        88903453        13537902123     332123
童云龙  34521113        88927528        13503793985     373985
童万贞  34521112        34523377        13803778530     338530

*/
数据文件 tel.csv
姓名,办电,宅电,手机,虚拟网
卢小珍,34521111,88903453,13537902123,332123
童云龙,34521113,88927528,13503793985,373985
童万贞,34521112,34523377,13803778530,338530
卢小珍,34521111,88903453,13537902123,332123
这个没看明白哦,姓名得是一个字段里面的,分别读取其中的卢小珍,童云龙,读姓名时不用读出来办电和手机的。。。这个是直接读取全部的内容咯
aabcg129 2017-11-17
  • 打赏
  • 举报
回复
引用 8 楼 zjq9931 的回复:
[quote=引用 7 楼 aabcg129 的回复:] [quote=引用 5 楼 zjq9931 的回复:] [quote=引用 4 楼 aabcg129 的回复:] 主要不能写死。。 T T 因为还会刷新文档内容,每次要覆盖一下的。。。。想不出来办法了
先把自己写的代码拿上来,给你改改是可以的。[/quote]嗯呢,谢谢大佬。。。不过现在只写了打开txt文档的代码,后面功能实现就不会了~ #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; if(NULL == (fp = fopen("host.txt", "r"))) { printf("error\n"); exit(1); } char ch; while(EOF != (ch=fgetc(fp))) { printf("%c", ch); } fclose(fp); return 0; } [/quote] fgetc换成fgets可以一次读取一行。 一行一行操作就容易理解一下。 每个字段的分割符用'\t'来分割。 strstr函数可以返回\t位置的指针,指针+1就是字段的内容。 结合一些字符串操作函数,就可以取出每个字段。[/quote] fgetc换成fgets 编译就报错了[Error] cannot convert 'FILE* {aka _iobuf*}' to 'char*' for argument '1' to 'char* fgets(char*, int, FILE*)' 然后各个字段怎么就能实现分开读取的情况,还请指教~有代码最好理解了
BlackHamlet 2017-11-17
  • 打赏
  • 举报
回复
引用 4 楼 aabcg129 的回复:
[quote=引用 1 楼 u011648839 的回复:] 不能用数组就用char*直接写死啊,就不能修改了 读的时候就一个字符一个字符比较呗,每个断句后加个自定义的标志比如\2读到了就表示改下一个信息了
主要不能写死。。 T T 因为还会刷新文档内容,每次要覆盖一下的。。。。想不出来办法了[/quote] 不能用数组的是没办法的 任何信息只要是连续的有序的同类的,都可以看做数组,并不是非得char a[10]才叫数组 只要你在内存里把张三这两个字排列出来,我就可以说这是一个数组
hongwenjun 2017-11-17
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <string.h>

int main()
{
    FILE* pFile;
    char* pch;
    char str [255] = {0};

    pFile = fopen("tel.csv" , "r");
    if (pFile == NULL) {
        perror("Error opening file");
        return -1;
    }
    fgets(str , 255 , pFile);
    while (! feof(pFile)) {
        pch = strtok(str, ",\n");
        while (pch != NULL) {
            printf("%s\t", pch);
            pch = strtok(NULL, ",\n");
        }
        printf("\n");
        fgets(str , 255 , pFile);  // 这样写法 解决BUG,不会输出最后一行的名字

    }
    fclose(pFile);
    return 0;
}
/* 输出结果
姓名    办电    宅电    手机    虚拟网
卢小珍  34521111        88903453        13537902123     332123
童云龙  34521113        88927528        13503793985     373985
童万贞  34521112        34523377        13803778530     338530

*/
数据文件 tel.csv
姓名,办电,宅电,手机,虚拟网
卢小珍,34521111,88903453,13537902123,332123
童云龙,34521113,88927528,13503793985,373985
童万贞,34521112,34523377,13803778530,338530
卢小珍,34521111,88903453,13537902123,332123
  • 打赏
  • 举报
回复
引用 7 楼 aabcg129 的回复:
[quote=引用 5 楼 zjq9931 的回复:] [quote=引用 4 楼 aabcg129 的回复:] 主要不能写死。。 T T 因为还会刷新文档内容,每次要覆盖一下的。。。。想不出来办法了
先把自己写的代码拿上来,给你改改是可以的。[/quote]嗯呢,谢谢大佬。。。不过现在只写了打开txt文档的代码,后面功能实现就不会了~ #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; if(NULL == (fp = fopen("host.txt", "r"))) { printf("error\n"); exit(1); } char ch; while(EOF != (ch=fgetc(fp))) { printf("%c", ch); } fclose(fp); return 0; } [/quote] fgetc换成fgets可以一次读取一行。 一行一行操作就容易理解一下。 每个字段的分割符用'\t'来分割。 strstr函数可以返回\t位置的指针,指针+1就是字段的内容。 结合一些字符串操作函数,就可以取出每个字段。
aabcg129 2017-11-17
  • 打赏
  • 举报
回复
引用 5 楼 zjq9931 的回复:
[quote=引用 4 楼 aabcg129 的回复:] 主要不能写死。。 T T 因为还会刷新文档内容,每次要覆盖一下的。。。。想不出来办法了
先把自己写的代码拿上来,给你改改是可以的。[/quote]嗯呢,谢谢大佬。。。不过现在只写了打开txt文档的代码,后面功能实现就不会了~ #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; if(NULL == (fp = fopen("host.txt", "r"))) { printf("error\n"); exit(1); } char ch; while(EOF != (ch=fgetc(fp))) { printf("%c", ch); } fclose(fp); return 0; }
aabcg129 2017-11-17
  • 打赏
  • 举报
回复
引用 3 楼 cfjtaishan 的回复:
这个问题不是特别难吧;不能使用数组是啥个意思? 我定义一个数组(结构体),然后读文件到内存(申请的数组就在内存里),这样通过遍历内存里的数据可以得到对应的某行末列的数值;

struct person_info {
    char name[32];
    int age;
    char sex[6];
    char tel[16];
    char address[32];
};
读得时候建议使用fscanf,因为文件数据很有规则;
struct person_info info;
fscanf("%s %d %s %s %s\n", info.name, &info.age, info.sex, info.tel, info.address);
方法可以参考一下;有问题可以继续提出来。
谢谢大佬~应该是可以用数组的,不能用数组的话我也不知道怎么写,当时老师说的有些快,应该是听错了需求。。。。现在仅仅会fopen整个txt 现在读取是没问题,就是在选项那一块不懂,怎么做就可以实现输入age 再输入行数,然后定位到年龄,这一块不知道怎么写
  • 打赏
  • 举报
回复
引用 4 楼 aabcg129 的回复:
主要不能写死。。 T T 因为还会刷新文档内容,每次要覆盖一下的。。。。想不出来办法了
先把自己写的代码拿上来,给你改改是可以的。
aabcg129 2017-11-17
  • 打赏
  • 举报
回复
引用 1 楼 u011648839 的回复:
不能用数组就用char*直接写死啊,就不能修改了 读的时候就一个字符一个字符比较呗,每个断句后加个自定义的标志比如\2读到了就表示改下一个信息了
主要不能写死。。 T T 因为还会刷新文档内容,每次要覆盖一下的。。。。想不出来办法了
自信男孩 2017-11-17
  • 打赏
  • 举报
回复
这个问题不是特别难吧;不能使用数组是啥个意思? 我定义一个数组(结构体),然后读文件到内存(申请的数组就在内存里),这样通过遍历内存里的数据可以得到对应的某行末列的数值;

struct person_info {
    char name[32];
    int age;
    char sex[6];
    char tel[16];
    char address[32];
};
读得时候建议使用fscanf,因为文件数据很有规则;
struct person_info info;
fscanf("%s %d %s %s %s\n", info.name, &info.age, info.sex, info.tel, info.address);
方法可以参考一下;有问题可以继续提出来。
老马何以识途 2017-11-17
  • 打赏
  • 举报
回复
平台关系很大啊,如果有类似于getline这样的函数,就一行一行读,然后套用相同的规则去解析出各字段。 当然如果没有也没关系,读到\n就是一行嘛
BlackHamlet 2017-11-17
  • 打赏
  • 举报
回复
不能用数组就用char*直接写死啊,就不能修改了 读的时候就一个字符一个字符比较呗,每个断句后加个自定义的标志比如\2读到了就表示改下一个信息了
aabcg129 2017-11-17
  • 打赏
  • 举报
回复
引用 20 楼 zhao4zhong1 的回复:
[quote=引用 19 楼 hzy_76 的回复:] 上面有朋友给出fsanf的方法,应该可行,不过format中的\n应该不要,即这样写:

fscanf("%s %d %s %s %s", name, &age, sex, tel, address);
你必须把所有列都一次性读出来,只是某些列不用来显示罢了,此时文件指针会自动往后移。 无意义并且无规则的行,可以用读行的函数读出来后不处理,使文件指针后移。
不要的列可以在%后面加*跳过。[/quote]受教了!
老马何以识途 2017-11-17
  • 打赏
  • 举报
回复
受教了,谢谢!
赵4老师 2017-11-17
  • 打赏
  • 举报
回复
引用 19 楼 hzy_76 的回复:
上面有朋友给出fsanf的方法,应该可行,不过format中的\n应该不要,即这样写:

fscanf("%s %d %s %s %s", name, &age, sex, tel, address);
你必须把所有列都一次性读出来,只是某些列不用来显示罢了,此时文件指针会自动往后移。 无意义并且无规则的行,可以用读行的函数读出来后不处理,使文件指针后移。
不要的列可以在%后面加*跳过。
老马何以识途 2017-11-17
  • 打赏
  • 举报
回复
上面有朋友给出fsanf的方法,应该可行,不过format中的\n应该不要,即这样写:

fscanf("%s %d %s %s %s", name, &age, sex, tel, address);
你必须把所有列都一次性读出来,只是某些列不用来显示罢了,此时文件指针会自动往后移。 无意义并且无规则的行,可以用读行的函数读出来后不处理,使文件指针后移。
aabcg129 2017-11-17
  • 打赏
  • 举报
回复
//#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
int main(void)
{
FILE *fp = NULL;
char buf[1024] = {0};
int count = 0;
int row = 0;
int ch = 0;
fp = fopen("host.txt", "r");
if (fp == NULL)
{
printf("Cann't open the file!\n");
exit(1);
}
else
{
while (1)
{
printf("Input a row you want to read: \n");
scanf("%d", &row);

fflush(stdin);
while (!feof(fp))
{
fgets(buf, 1024, fp);
count++;
if (row == count)
{
printf("%s", buf);
}
memset(buf, 0, sizeof(buf));
}
count = 0;
rewind(fp);
printf("go on? [y/n]: ");
scanf("%c", &ch);
fflush(stdin);
if (ch == 'y' || ch == 'Y')
{
continue;
}
else
{
break;
}
}
fclose(fp);
}
return 0;
}
刚在网上看到或者读任意一行的代码~但还是不知道如何把name字段下的东西放进一个组里~啊啊啊啊啊~哪位大神能写个代码啊啊啊啊~抓狂ing ~img=https://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/003/monkey/50.gif][/img]
aabcg129 2017-11-17
  • 打赏
  • 举报
回复
引用 16 楼 cfjtaishan 的回复:
[quote=引用 6 楼 aabcg129 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 这个问题不是特别难吧;不能使用数组是啥个意思? 我定义一个数组(结构体),然后读文件到内存(申请的数组就在内存里),这样通过遍历内存里的数据可以得到对应的某行末列的数值;

struct person_info {
    char name[32];
    int age;
    char sex[6];
    char tel[16];
    char address[32];
};
读得时候建议使用fscanf,因为文件数据很有规则;
struct person_info info;
fscanf("%s %d %s %s %s\n", info.name, &info.age, info.sex, info.tel, info.address);
方法可以参考一下;有问题可以继续提出来。
谢谢大佬~应该是可以用数组的,不能用数组的话我也不知道怎么写,当时老师说的有些快,应该是听错了需求。。。。现在仅仅会fopen整个txt 现在读取是没问题,就是在选项那一块不懂,怎么做就可以实现输入age 再输入行数,然后定位到年龄,这一块不知道怎么写[/quote] 你先将文件内容读到一个数组里,这个数据建议用malloc/realloc申请空间,因为读文件不知道文件有多少个人的信息; 用户输入age时,你就循环遍历数组,一个个比较,若相等直接输出下表即可。因为数组下表就是在文件内的第几行(数组下表是从0开始)[/quote] 太高深了~实在不明白~不过还是谢谢您~
自信男孩 2017-11-17
  • 打赏
  • 举报
回复
引用 6 楼 aabcg129 的回复:
[quote=引用 3 楼 cfjtaishan 的回复:] 这个问题不是特别难吧;不能使用数组是啥个意思? 我定义一个数组(结构体),然后读文件到内存(申请的数组就在内存里),这样通过遍历内存里的数据可以得到对应的某行末列的数值;

struct person_info {
    char name[32];
    int age;
    char sex[6];
    char tel[16];
    char address[32];
};
读得时候建议使用fscanf,因为文件数据很有规则;
struct person_info info;
fscanf("%s %d %s %s %s\n", info.name, &info.age, info.sex, info.tel, info.address);
方法可以参考一下;有问题可以继续提出来。
谢谢大佬~应该是可以用数组的,不能用数组的话我也不知道怎么写,当时老师说的有些快,应该是听错了需求。。。。现在仅仅会fopen整个txt 现在读取是没问题,就是在选项那一块不懂,怎么做就可以实现输入age 再输入行数,然后定位到年龄,这一块不知道怎么写[/quote] 你先将文件内容读到一个数组里,这个数据建议用malloc/realloc申请空间,因为读文件不知道文件有多少个人的信息; 用户输入age时,你就循环遍历数组,一个个比较,若相等直接输出下表即可。因为数组下表就是在文件内的第几行(数组下表是从0开始)
加载更多回复(1)

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧