如何使用fgets检查文件是否每行仅含一个单词?新手求助
解决每行仅含一个单词的文件校验与单词提取问题
你的核心需求是只提取每行恰好包含一个有效单词的行,跳过内容不符合的行。下面是修改后的代码,以及关键逻辑的说明:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> // 假设这些宏已提前定义 #define MAX_WORDS 1000 #define MAX_WORD_LEN 64 #define MAX_LINE_LEN 256 char* allocate_word_memory(const char* word) { char* ptr = malloc(strlen(word) + 1); if (ptr) { strcpy(ptr, word); } return ptr; } const char *get_word_from_file(FILE *file) { char words[MAX_WORDS][MAX_WORD_LEN]; char buf[MAX_LINE_LEN]; size_t idx = 0; while (fgets(buf, sizeof(buf), file)) { // 移除行尾的换行符(如果存在) size_t len = strlen(buf); if (len > 0 && buf[len-1] == '\n') { buf[len-1] = '\0'; } // 提取第一个有效单词 char *word = strtok(buf, " ?.,-\""); if (!word) { // 空行或全是分隔符,直接跳过 continue; } // 检查该行是否存在第二个有效单词 char *next_word = strtok(NULL, " ?.,-\""); if (next_word) { // 一行有多个单词,跳过 continue; } // 确保单词长度不超过数组限制,避免溢出 if (strlen(word) >= MAX_WORD_LEN) { continue; } // 符合条件,存入单词数组 strcpy(words[idx], word); ++idx; // 防止数组越界 if (idx >= MAX_WORDS) { break; } } fclose(file); srandom(time(NULL)); if (idx == 0) { // 无有效单词时返回NULL,可根据需求调整逻辑 return NULL; } int random_number = random() % idx; char *random_word = words[random_number]; char *verified_random_word = allocate_word_memory(random_word); return verified_random_word; }
关键改动说明
- 清理换行符:用
strlen定位行尾的\n并替换为终止符,避免后续判断时被当成分隔符干扰结果。 - 单行单单词校验:
- 先提取第一个有效单词,无有效单词则直接跳过该行;
- 尝试提取第二个单词,若能提取到则判定该行不符合要求,直接跳过;
- 边界安全处理:
- 检查单词长度是否超过数组限制,避免拷贝时溢出;
- 限制数组存储数量不超过
MAX_WORDS,防止越界; - 增加
idx == 0的判断,避免无有效单词时random() % 0触发错误。
补充提示
原代码在函数内直接执行fclose(file),如果调用者后续还需要操作该文件指针会出现问题。若文件是由调用者打开的,建议将fclose(file)移到函数外部,由调用者负责文件生命周期管理。
内容的提问来源于stack exchange,提问作者Robbedbark455
相关产品推荐
相关产品推荐

