C语言:用scanf读取文件单词、识别<开头token及验证函数正确性
用scanf(fscanf)读取文件单词+识别Mad-Lib Token的完整解决方案
我来一步步帮你搞定这两个问题,全都是基于你要求的scanf系列函数来实现的,还会附上验证方法:
一、怎么用fscanf读取文件里的每个单词
首先得明确:如果是读文件内容,咱们要用fscanf()而不是默认读标准输入的scanf()。%s格式符天生就会以空格、换行、制表符这些空白字符分隔单词,刚好满足咱们读单个单词的需求。
给你个基础框架代码:
#include <stdio.h> #include <stdbool.h> #include <string.h> #define MAX_WORD_LEN 100 // 你可以根据实际需求调整单词的最大长度 int main() { // 打开输入文件,注意替换成你的文件名 FILE* in_file = fopen("in.txt", "r"); if (in_file == NULL) { perror("打开文件失败"); return 1; } char word[MAX_WORD_LEN]; // 循环读每个单词,直到文件读完 while (fscanf(in_file, "%s", word) != EOF) { printf("读到单词:%s\n", word); // 这里可以调用后面写的Token识别函数 } fclose(in_file); return 0; }
二、编写识别<开头Token的bool函数
咱们要写的函数,每次从文件里读一个单词,判断它是不是以<开头的Mad-Lib占位符(也就是你说的token)。如果是就返回true,普通单词就返回false,还要处理文件读完的情况。
函数实现
// 从输入文件读一个单词,若为<开头的token返回true,否则返回false // 参数:文件指针、存单词的缓冲区、缓冲区大小(防止溢出) bool is_madlib_token(FILE* in_file, char* word_buffer, int buffer_size) { // 先读一个单词,限制读取长度为buffer_size-1,留位置存结束符 if (fscanf(in_file, "%*s", word_buffer, buffer_size - 1) == EOF) { return false; // 文件读完了,没单词了 } // 检查首字符是不是'<' if (word_buffer[0] == '<') { // 可选:题目说<>内部无空格,咱们可以额外验证是不是有闭合的'>' size_t word_len = strlen(word_buffer); if (word_len >= 2 && word_buffer[word_len - 1] == '>') { return true; } // 如果题目只要求以<开头就算token,把上面的验证删掉,直接return true就行 } return false; }
几个关键点提醒:
- 一定要传缓冲区大小,用限制长度的格式符避免长单词把缓冲区撑爆(安全第一!)
- 文件指针会自动往后走,不用手动调整位置
- 要是你不需要验证闭合的
>,直接判断首字符是<就返回true就行,完全看题目要求
三、怎么验证这个函数正常工作?
验证的核心就是:准备测试用的输入文件,调用函数然后对比输出和预期是否一致。
1. 先准备测试文件in.txt
比如写这样的内容:
I have really <adjective> eyes My <noun> is so <color>
2. 写验证代码
把刚才的函数整合进去,跑一遍看看结果:
int main() { FILE* in_file = fopen("in.txt", "r"); if (in_file == NULL) { perror("打开文件失败"); return 1; } char word[MAX_WORD_LEN]; printf("测试Token识别结果:\n"); while (true) { bool is_token = is_madlib_token(in_file, word, MAX_WORD_LEN); if (feof(in_file)) { break; } if (is_token) { printf("找到Token:%s\n", word); } else { printf("普通单词:%s\n", word); } } fclose(in_file); return 0; }
3. 预期输出
如果函数正常工作,你会看到:
测试Token识别结果: 普通单词:I 普通单词:have 普通单词:really 找到Token:<adjective> 普通单词:eyes 普通单词:My 找到Token:<noun> 普通单词:is 普通单词:so 找到Token:<color>
另外还可以测试一些边界情况:
- 空文件:函数会直接返回false,循环立刻退出
- 只有单个
<的单词:如果加了闭合验证会返回false,没加的话返回true,根据你的需求调整 - 以
<开头但没>的单词:比如<adjective,同样看你要不要把它算成有效Token
最后几个小提醒
- 缓冲区大小别设太小,不然长单词会被截断
- 每次打开文件一定要检查返回值,别忽略空指针的情况
- 如果你的输入文件里有特殊字符,
%s可能读不了,但题目里说单词是正常的Mad-Lib格式,所以没问题
内容的提问来源于stack exchange,提问作者Stacy Willis
相关产品推荐
相关产品推荐

