C语言查找TXT文件中指定字符所在行及行内位置的优雅方案
可选的优雅实现方案
方案1:fgets + strchr组合(通用性最强,实现简洁)
这种方案不需要逐字符调用getchar,每读取一行后直接用C标准库的strchr批量定位目标字符,自动计算行内偏移,代码逻辑紧凑,可移植性覆盖所有符合C标准的平台。
示例实现:
#include <stdio.h> #include <string.h> #define BUF_SIZE 4096 int main(void) { FILE *fp = fopen("test.txt", "r"); if (!fp) { perror("fopen failed"); return 1; } char buf[BUF_SIZE]; long line_num = 1; while (fgets(buf, BUF_SIZE, fp) != NULL) { char *pos = strchr(buf, 'X'); while (pos != NULL) { // 行内位置从1开始计数,如需从0开始去掉+1即可 printf("找到'X',行号:%ld,行内位置:%td\n", line_num, pos - buf + 1); pos = strchr(pos + 1, 'X'); } // 仅当当前行完整读入(末尾有换行)时行号+1,避免长行被拆成多段重复计数 if (strchr(buf, '\n')) { line_num++; } } fclose(fp); return 0; }
如果需要处理任意长度的长行,可以把fgets替换为POSIX标准的getline,无需手动管理缓冲区大小,进一步简化逻辑。
方案2:内存映射文件(大文件场景性能最优)
如果需要处理GB级的大体积文本文件,内存映射可以省去用户态缓冲区反复拷贝的开销,直接将整个文件映射到进程地址空间,当做普通字符串遍历即可,性能远高于常规IO方案。
POSIX平台示例实现:
#include <stdio.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> int main(void) { int fd = open("test.txt", O_RDONLY); if (fd < 0) { perror("open failed"); return 1; } struct stat st; if (fstat(fd, &st) < 0) { perror("fstat failed"); close(fd); return 1; } char *file_addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (file_addr == MAP_FAILED) { perror("mmap failed"); close(fd); return 1; } long line_num = 1; char *line_start = file_addr; for (char *p = file_addr; p < file_addr + st.st_size; p++) { if (*p == '\n') { line_num++; line_start = p + 1; continue; } if (*p == 'X') { printf("找到'X',行号:%ld,行内位置:%td\n", line_num, p - line_start + 1); } } munmap(file_addr, st.st_size); close(fd); return 0; }
Windows平台可以用CreateFileMapping + MapViewOfFile实现相同逻辑。
内容的提问来源于stack exchange,提问作者mori
相关产品推荐
相关产品推荐

