| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6845 人关注过本帖
标题:新人上路,不懂就问。。大神求教!!
只看楼主 加入收藏
唯光阿九
Rank: 2
等 级:论坛游民
帖 子:21
专家分:59
注 册:2016-6-10
结帖率:100%
收藏
已结贴  问题点数:30 回复次数:10 
新人上路,不懂就问。。大神求教!!
学校一个作业。。想了一段时间了,网上找不到类似的,看书,书上有些地方也不是很懂。。所以还是努力自己写了一个C。写得可能有点蠢,希望各路大神不吝赐教。。
程序代码:
/*
    编写一程序P337.C实现以下功能
  有一存储很多学生成绩的文本文件(学生与课程数不限),每个学生的数据包括学号(10个数字)、姓名(最多4个汉字)、性别、
    课程名称(最多7个汉字)、成绩(整数)。从键盘输入某个学生的姓名,要求在文件中查找有无其成绩记录(可能有多条记录或没有),
    然后在屏幕上显示出相应的信息。
  单击此处下载程序运行时测试用的学生成绩文件xscj.txt并保存到程序P337.C所在的文件夹且文件名保持不变。
    编程可用素材:printf("请输入要查找成绩的学生姓名:")、printf("文件打开失败,请检查文件名及路径是否正确、文件是否存在!")、
    printf("\n查找结果为:\n")、printf("文件中没有找到姓名为“…”的学生\n"…。
  程序的运行效果应严格地如图1、图2、图3所示,图中的红色部分是从键盘输入的内容。
*/
#include <stdio.h>
#include <string.h>

typedef struct xuesheng
{
    int xuehao[3];
    char mingzi[20];
    char xingbie[5];
    char kemu[30];
    int chengji;
}DENGJI;            /*结构体定义*/

int main(void)
{
    FILE *fp;
    DENGJI chazhao[30];    
    char shuru[10];                /*输入存入该字符串变量*/
    int i, flag = 0, count = 0;   /*定义标记和序号计数并赋值为0*/

    fp = fopen("xscj.txt", "r");
    if (fp == NULL)
    {
        printf("文件打开失败,请检查文件名及路径是否正确、文件是否存在!");
        return 0;
    }                           /*判断文件是否正常打开*/
    printf("请输入要查找成绩的学生姓名:");
    gets(shuru);                /*输入名字*/
    while (!feof(fp))
    {
        i = 0;
        fscanf(fp, "%s, %s, %s, %s, %d",
               chazhao[i].xuehao, chazhao[i].mingzi, chazhao[i].xingbie, chazhao[i].kemu, &chazhao[i].chengji);
        i++;    
    }                            /*将文件内容读入结构体数组*/
    while (!feof(fp))
    { 
        i = 0;
        if (strcmp(chazhao[i].mingzi, shuru) == 0)
        {
            flag = 1;
            break;
        }                    /*判断是否有结构体元素成员与输入名字相等,并将标记赋值退出循环*/
        else
        {
            flag = 0;
        }                      
        i++;
    }
    if (flag == 0)
    {
        printf("文件中没有找到姓名为“%s”的学生\n", shuru);
        return 0;
    }                            /*标记为0说明上一次循环查找没有所寻值*/
    if (flag == 1)
    {
        printf("\n查找结果为:\n");
        while (!feof(fp))
        {
            i = 0;
            if (strcmp(chazhao[i].mingzi, shuru) == 0)
            {
                count++;              /*判断成功,序号赋值*/
                printf("%d, %s, %s, %s, %s, %d\n",count, chazhao[i].xuehao, chazhao[i].mingzi, chazhao[i].xingbie, chazhao[i].kemu, chazhao[i].chengji);                /*输出结果*/
            }
            i++;
        }
                return 0;
    }                                            
}

xscj.zip (738 Bytes)

xscj的文件。
搜索更多相关主题的帖子: 文本文件 汉字 记录 键盘 
2016-06-11 14:32
唯光阿九
Rank: 2
等 级:论坛游民
帖 子:21
专家分:59
注 册:2016-6-10
收藏
得分:0 
忘了贴图了,囧
图片附件: 游客没有浏览图片的权限,请 登录注册
2016-06-11 14:40
随风飘荡
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:3
帖 子:208
专家分:598
注 册:2011-9-9
收藏
得分:15 
那么,你的问题是什么?
2016-06-11 16:07
唯光阿九
Rank: 2
等 级:论坛游民
帖 子:21
专家分:59
注 册:2016-6-10
收藏
得分:0 
(⊙o⊙)…忘了说了。。程序运行有问题。。每一次都是“文件中没有找到姓名为“%s”的学生”
我不知道是不是flag赋值出错了。。还是其他地方出了问题。。各位大神帮帮忙啊。。
2016-06-11 20:34
随风飘荡
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:3
帖 子:208
专家分:598
注 册:2011-9-9
收藏
得分:0 
逻辑错了,我加注释的行你自己看看应该怎么改,改完了还有问题再继续问。
实际上查找是否存在和输出能合并,没有必要分开。但你先改好能运行了再想想怎么合并。


程序代码:
int main(void)
{
    FILE *fp;
    DENGJI chazhao[30];    
    char shuru[10];                /*输入存入该字符串变量*/
    int i, flag = 0, count = 0;   /*定义标记和序号计数并赋值为0*/

    fp = fopen("xscj.txt", "r");
    if (fp == NULL)
    {
        printf("文件打开失败,请检查文件名及路径是否正确、文件是否存在!");
        return 0;
    }                           /*判断文件是否正常打开*/
    printf("请输入要查找成绩的学生姓名:");
    gets(shuru);                /*输入名字*/
    while (!feof(fp))
    {
//        i = 0;  使i多次为0,没有自增的意义
        fscanf(fp, "%s, %s, %s, %s, %d",
               chazhao[i].xuehao, chazhao[i].mingzi, chazhao[i].xingbie, chazhao[i].kemu, &chazhao[i].chengji);
        i++;    
    }                            /*将文件内容读入结构体数组*/
    while (!feof(fp)) //在上面就已经读到文件尾了,永远为0,也就是这个while进不去
    { 
//        i = 0;  为什么每个循环体里都有这个,和上面一样,多次为0,而且i变量你到底是想用来做下标还是做计数变量的?
        if (strcmp(chazhao[i].mingzi, shuru) == 0)
        {
            flag = 1;
            break;
        }                    /*判断是否有结构体元素成员与输入名字相等,并将标记赋值退出循环*/
/*        else
        {
            flag = 0;
        }                      不需要设置为0,flag初始值就被你设置为0了*/
//         i++;  如果是计数变量,那么在文件已经读取完毕后你还改他不合适,如果不是,怎么修改自己想想。
    }
    if (flag == 0)
    {
        printf("文件中没有找到姓名为“%s”的学生\n", shuru);
        return 0;
    }                            /*标记为0说明上一次循环查找没有所寻值*/
    if (flag == 1)
    {
        printf("\n查找结果为:\n");
        while (!feof(fp)) //和上面一个问题,怎么改?
        {
//            i = 0; 一样
            if (strcmp(chazhao[i].mingzi, shuru) == 0)
            {
                count++;              /*判断成功,序号赋值*/
                printf("%d, %s, %s, %s, %s, %d\n",count, chazhao[i].xuehao, chazhao[i].mingzi, chazhao[i].xingbie, chazhao[i].kemu, chazhao[i].chengji);                /*输出结果*/
            }
//            i++; 一样
        }
                return 0;
    }                                            
}
2016-06-11 23:14
lanke711
Rank: 9Rank: 9Rank: 9
来 自:流浪在天国之路
等 级:蜘蛛侠
威 望:7
帖 子:317
专家分:1437
注 册:2015-7-16
收藏
得分:7 
程序代码:
 while (!feof(fp))    //总结,在里面i=0,i++;再i=0,i++;......最后它会是多少??楼主这样i有什么用处?
    {
        i = 0;        //在while里面初始化为0??
        fscanf(fp, "%s, %s, %s, %s, %d",
               chazhao[i].xuehao, chazhao[i].mingzi, chazhao[i].xingbie, chazhao[i].kemu, &chazhao[i].chengji);
        i++;                //这里每次循环递增
    }                            /*将文件内容读入结构体数组*/
    while (!feof(fp))
    { 
        i = 0;//初始化为0
        if (strcmp(chazhao[i].mingzi, shuru) == 0)
        {
            flag = 1;
            break;
        }                    /*判断是否有结构体元素成员与输入名字相等,并将标记赋值退出循环*/
        else
        {
            flag = 0;
        }                      
        i++;//递增
    }
    if (flag == 0)
    {
        printf("文件中没有找到姓名为“%s”的学生\n", shuru);
        return 0;
    }                            /*标记为0说明上一次循环查找没有所寻值*/
    if (flag == 1)
    {
        printf("\n查找结果为:\n");
        while (!feof(fp))
        {
            i = 0;//初始化为0
            if (strcmp(chazhao[i].mingzi, shuru) == 0)
            {
                count++;              /*判断成功,序号赋值*/
                printf("%d, %s, %s, %s, %s, %d\n",count, chazhao[i].xuehao, chazhao[i].mingzi, chazhao[i].xingbie, chazhao[i].kemu, chazhao[i].chengji);                /*输出结果*/
            }
            i++;//递增
        }
                return 0;
    }                                            
}

楼主的代码真的。。。。。
我的思路很简单:
int i=0
while(!feof(fp))
{
    fscanf();
    i++;//计次得到获取的循环次数
}
for(int j=0;j<i;j++)
{
    if((strcmp())==0)
    {
        //输出找到学生的信息。
        continue;
    }
    else
    {
        //找不到学生的信息,并执行退出查询
        
    }
}

不需要这么复杂,用到flags来标记循环。可以直接if。。。else里面写的内容,为什么要弄个标记,把内容移出外面再写一次,楼主不觉得你这样的思路有点奇怪吗???
在每条循环语句里初始化计次变量,下面再递增...不知道楼主有没有仔细看?还是不明白循环的原理?这样循环,计次变量i还有什么用?

普通人之所以普通,是因为他们普遍有一个通病,那就是认为自己永远普通。
千夫所指,我亦坚持。就算被所有人误解,我也照样守护这一切。
我们总是觉得,这些灵魂的表情,傲慢自大,目中无人,其实,真正目中无人的是我们。它们傲慢的不过是表情,而我们傲慢的却是行为!
记得,是为了忘记!
只要想着有那么一天,我就能忍受现在的每一天!
灾难并不可怕,可怕的是心中没有了希望。
你以为我在天堂,其实我正在路上。
当你觉得自己走不到终点的时候,请不要放弃。或许你的对手也是这种感觉。
2016-06-11 23:24
唯光阿九
Rank: 2
等 级:论坛游民
帖 子:21
专家分:59
注 册:2016-6-10
收藏
得分:0 
谢谢哈,有点不好意思了。。。新手,犯了这么大的基本性错误。但是我在你的指导下认真修改了下程序。
改成这个样子了,精简改短了很多,你看看。
程序代码:
#include <stdio.h>
#include <string.h>

typedef struct xuesheng
{
    int xuehao[3];
    char mingzi[20];
    char xingbie[5];
    char kemu[30];
    int chengji;
}DENGJI;

int main(void)
{
    FILE *fp;
    DENGJI chazhao[30];    
    char shuru[10];
    int i = 0, flag = 0, count = 0;

    fp = fopen("xscj.txt", "r");
    if (fp == NULL)
    {
        printf("文件打开失败,请检查文件名及路径是否正确、文件是否存在!");
        return 0;
    }
    printf("请输入要查找成绩的学生姓名:");
    gets(shuru);                                           /前面都一样,只是多一个将i初始化为0了/
    while (!feof(fp))
    {
        fscanf(fp, "%s, %s, %s, %s, %d",
               chazhao[i].xuehao, chazhao[i].mingzi, chazhao[i].xingbie, chazhao[i].kemu, &chazhao[i].chengji);
        i++;
    }                                                       /这个循环就是给结构体里面所有成员全部初始化的,所以i就是一个循环计数,从一个数组成员跳到下一个元素/
    rewind(fp);                                            /重置指针位置,方便下一次循环/
    i = 0;
    while (!feof(fp))
    { 
        if (strcmp(chazhao[i].mingzi, shuru) == 0)
        {
            flag = 1;
            count++;
            printf("%d, %s, %s, %s, %s, %d\n",count, chazhao[i].xuehao, chazhao[i].mingzi, chazhao[i].xingbie, chazhao[i].kemu, chazhao[i].chengji);
        }
        i++;
    }                                                        /我在这里合并了判断与输出,flag赋值是只在判断成立时赋值了/
    if (flag == 0)                                                /如果上面一步不成立,就可以直接判断flag为0的情况了了/ 
    {
        printf("文件中没有找到姓名为“%s”的学生\n", shuru);
    }
    fclose(fp);                                                 /上面写的那个C忘了关闭指针。。/
    return 0;
}

但是我写完调试时发现结构体数组越界了。程序好像直接把一行的全部弄到一个结构数组成员里去了,而那第一个循环也成了一个死循环。最后造成数组越界。(好像是把空格及其之后的内容读到一个字符串数组里去了)文件里面是这个样子,这个怎么结决呢?
图片附件: 游客没有浏览图片的权限,请 登录注册
2016-06-12 01:01
唯光阿九
Rank: 2
等 级:论坛游民
帖 子:21
专家分:59
注 册:2016-6-10
收藏
得分:0 
回复 6楼 lanke711
这个每个人学习时的情况不一样吧。我脑壳比较笨。。。我的意思原本是这样的:如果可以的话,直接用指针在文件里寻找得到比较相同的位置,将当前位置用指针再次赋值到一个结构体或者一个字符串里都可以,但如你所见,楼主能力有限,很多地方不会。然后返回来用循环做的时候又想不出简单的方法了,这个样子写出来的时候其实我本身就有很多疑问,所以才来求教各路高手啦。。
2016-06-12 01:10
gz1347351162
Rank: 2
等 级:论坛游民
帖 子:19
专家分:44
注 册:2016-5-30
收藏
得分:8 
我也是新手,也有个疑问。fscanf函数是遇到空格或者回车就返回了,
 fscanf(fp, "%s, %s, %s, %s, %d",
               chazhao[i].xuehao, chazhao[i].mingzi, chazhao[i].xingbie, chazhao[i].kemu, &chazhao[i].chengji);
        i++;
这样会不会导致你把文件里的内容都读到结构体数组成员的第一个字段了,也就是说每个结构体只有第一个字段被赋值了,如果是这样数组就越界了,还有个问题就是是不是应该把你格式控制中的,去掉才与文本中的格式严格对应啊
2016-06-12 12:55
随风飘荡
Rank: 7Rank: 7Rank: 7
等 级:黑侠
威 望:3
帖 子:208
专家分:598
注 册:2011-9-9
收藏
得分:0 
这里有三个问题
1. LS说的是对的。你的fscanf里面每个格式控制符后面都有逗号,而文件里没有,这会导致fscanf中断。文件指针无法向前,永远到达不了EOF,死循环产生了。
2. 你的xuehao是一个int[3]的数组。这显然不能这样用,但是实际上在int[3]至少有12个char的空间,所以你这个还没出现问题,这就是C的危险性,也是灵活性。
3. 第一个循环把文件内容读出来了之后,为了搜索名字重新读一次,真的有必要吗?那第一次读出来是为了什么目的呢?
2016-06-12 13:05
快速回复:新人上路,不懂就问。。大神求教!!
数据加载中...
 
   



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

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