目录
①、年月日经过n天后的日期
②、坐标排序
③、统计文件中出现某个单词的次数
④、输出含for的行
⑤、比较两个文本是否相等
①、年月日经过n天后的日期
题述:定义包含年月日表示的日期的结构体,写程序实现计算某年某月某日过n天后的日期是哪年哪月哪日
思路:
1、这种题因为关于年了,那就应该判断是闰年还是平年,因为会导致2月的天数不同,闰年2月29天。
2、越界问题,无非是月越界或者年越界,因为过n天,这个n你没有指定范围,那他可以无限大也可以无限小,当天数超过本月应有的天数时,月份应该++,并且n应该减掉本月天数。如果月份>12了,年份应该++,并且再判断,上述过程全放在while循环中,直到n是一个正常的月份天数为止。
#include<stdio.h>
typedef struct date
{
int year, month, day;
}date;
int main()
{ //闰年二月有29天
int day[2][13] = { {0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31} };
date a = { 0 };
printf("请输入年月日:>\n");
scanf("%d %d %d", &a.year, &a.month, &a.day);
int leap = (a.year % 400 == 0) || ((a.year % 4 == 0) && (a.year % 100 == 0));
int n = 0;
printf("请输入过多少天:>\n");
scanf("%d", &n);
a.day += n;
while (a.day > day[leap][a.month])
{//为什么是while循环,因为你输入的天数没有限制范围,他可能很大也可能很小
a.day -= day[leap][a.month];
a.month++;
if (a.month > 12)
{
a.month %= 12;
a.year++;
//那么年数变了,还要再次判断是否是闰年
leap = (a.year % 400 == 0) || ((a.year % 4 == 0) && (a.year % 100 == 0));
}
}
printf("经过%d天后为%d年%d月%d日\n",n, a.year, a.month, a.day);
system("pause");
return 0;
}
②、坐标排序
题述:输入n个点,对这些点的x轴坐标排序并输出
思路:关键就是冒泡排序的应用罢了
#include<stdio.h>
typedef struct
{
int x, y;
}coord;
int main()
{
int n = 0;
printf("你想输入几个坐标:>\n");
scanf("%d", &n);
coord s[20];
for (int i = 0; i < n; i++)
{
scanf("%d %d", &s[i].x, &s[i].y);
}
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - 1 - i; j++)
{
if (s[j].x > s[j+1].x)
{
int temp = s[j].x;
s[j].x = s[j+1].x;
s[j+1].x = temp;
}
}
}
for (int i = 0; i < n; i++)
{
printf("第%d个坐标:(%d,%d)\n", i + 1, s[i].x, s[i].y);
}
return 0;
}
③、统计文件中出现某个单词的次数
题述:文件in.txt存放了一篇文章,从键盘输入某个单词,请统计文章中这个单词出现的次数并输出
思路:打开读取文章的文件,然后每次从文件中读取一行文本,(fgets每次读取一行,并且遇到失败或者读到文件结尾返回NULL,因此不能直接用过fgets的返回值来判断函数是否出错而终止,应借助feof函数或者ferror函数来判断)如果已经读到文件末尾则退出循环。在每一行文本中查找单词出现的位置,如果查找到则统计次数并指向单词后面一个字符的位置继续查找,直到这行文本中不存在单词为止。
#include <stdio.h>
#include <string.h>
#define MAX_LEN 1000 // 假设文章最大长度不超过1000
int main() {
char word[MAX_LEN]; // 用户输入的单词
char filename[] = "in.txt"; // 文章文件路径
char line[MAX_LEN]; // 保存读入的一行文本
int count = 0; // 统计单词出现次数的变量
FILE* file = fopen(filename, "r"); // 以只读方式打开文件
if (file == NULL) {
printf("Failed to open file '%s'.\n", filename);
return 1;
}
printf("Please input a word: ");
scanf("%s", word); // 读入一个单词
while (!feof(file)) { // 循环读取一行文本
fgets(line, MAX_LEN, file);
char* p = line;
while ((p = strstr(p, word)) != NULL) { // 查找单词出现的位置
count++;
p += strlen(word); // 指向单词后一个字符的位置
}
}
printf("The word '%s' appears %d time(s) in the article.\n", word, count);
fclose(file);
return 0;
}
④、输出含for的行
题述:输出文件中含字符串"for"的行
思路:这道题是第③道题的变形,但是这道题有两种方法。
法一、与③同样的方法,调用strstr
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 888
int main()
{
FILE* fp = fopen("a.txt", "r");
if (fp == NULL)
{
printf("文件打开错误!\n");
exit(0);
}
char s[N];
while(!feof(fp))
{
fgets(s, N, fp);//一次读取一行
char *p = s;//一个为了保存一个为了遍历
if (strstr(p, "for") != NULL)
{
printf("%s", s);
}
}
return 0;
}
法二、循环遍历一行的方法
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 888
int main()
{
FILE* fp = fopen("a.txt", "r");
if (fp == NULL)
{
printf("文件打开错误!\n");
exit(0);
}
char s[N];
while(!feof(fp))
{
fgets(s, N, fp);//一次读取一行
if (strlen(s) >= 3)
{
for (int i = 0; i < strlen(s) - 2; i++)
{
if (s[i] == 'f' && s[i + 1] == 'o' && s[i + 2] == 'r')
{
printf("%s", s);
}
}
}
}
return 0;
}
⑤、比较两个文本是否相等
题述:比较两个文本是否相等:比较两个文本文件内容是否相等,并输出两个文件中第一次不相同字符内容行号及列值。
思路:
1、我们可以一个一个字符比较,故用fgetc函数,那么循环终止条件应该是两个中有一个文件读到了文件尾
2、如果其中有一个文件读到了'\n',说明要换行,那么对应的列也要发生变化
3、如果读到的字符不相等有两种情况:要么就是有一个文件,或者两个文件都读到了文件尾标志EOF,要么就是字符不相等,并不是因为结束标志,这种情况需要打印行号和列号。
4、因为读到EOF和字符确实不相等的情况都会跳出循环,那我们就要判断,到底是因为读到结束标志了还是因为字符确实不相等。
#include <stdio.h>
int main( )
{
FILE* fp, * fp1;
int col1 = 1, row1 = 1, col2 = 1, row2 = 1;//两个文件内容行和列肯定都是从1开始的
char ch1, ch2;
//test与test1都是与当前程序在同一目录下的文件
fp = fopen("test.txt", "r");
fp1 = fopen("test1.txt", "r");
while (!feof(fp) || !feof(fp1))
{//循环继续的条件一定是两个文件都没读到文件尾
ch1 = fgetc(fp);
ch2 = fgetc(fp1);
if (ch1 == '\n')
{
row1++;//如果读到了换行,说明行数要++
col1 = 1;//换行后列数还要是1
}
if (ch2 == '\n')
{
row2++;
col2 = 1;
}
if (ch1 != ch2)
{
if (ch1 == EOF || ch2 == EOF) break;//如果其中一个文件结束了,就跳出循环,因为不相等包括结束的情况
printf("test\t行号:%d 列号:%d\n", row1, col1);//按要求,如果两个文件都没有结束的,就打印出行和列
printf("test1\t行号:%d 列号:%d\n", row2, col2);
break;//不相等就没有必要继续往下比了
}
else
{
col1++; col2++;//相等就列值++
}
}
if (ch1 == EOF && ch2 != EOF)//能比到EOF说明之前一定有字符是相等的
printf("test文件内容被包含在test1中");
if (ch2 == EOF && ch1 != EOF)
printf("test1文件内容被包含在test中");
if (ch1 == EOF && ch2 == EOF)
printf("两个文件完全相同!");
fclose(fp);
fclose(fp1);
fp = fp1 = NULL;
return 0;
}