如何在C语言中实现支持通用换行符的逐行读取?
问题描述
我编写的以下代码从标准输入逐行读取内容并执行相关操作,在Visual Studio中运行正常,但在Xcode中表现异常。经排查,问题由\n、\r和\n\r三种换行符的差异导致。
测试输入如下:
1 10 3 4 5 6 7
在Visual Studio中函数可正常逐行读取,但在Xcode中读取完第一行后,会读取到\n而非10\n。
原始代码:
int n = NMAXVAL; char line[MAXLINE]; int rowCount = 0; char* token = NULL; while (rowCount < n && fgets(line, MAXLINE, stdin)) { token = strtok(line, " "); checkToken(token, n); // do something rowCount++; }
解决方案
问题核心是不同系统换行符处理逻辑差异,加上fgets会将换行符读入缓冲区、strtok未将换行符纳入分隔符范围导致的。可以从以下几个维度修改代码:
1. 统一清理行尾的换行符
读取行内容后,主动移除末尾的\n、\r或\r\n,确保行内容格式一致:
while (rowCount < n && fgets(line, MAXLINE, stdin)) { // 清理行尾的各类换行符 size_t len = strlen(line); if (len > 0) { if (line[len-1] == '\n') { line[len-1] = '\0'; // 处理Windows风格的\r\n if (len > 1 && line[len-2] == '\r') { line[len-2] = '\0'; } } else if (line[len-1] == '\r') { line[len-1] = '\0'; } } token = strtok(line, " "); checkToken(token, n); // do something rowCount++; }
2. 扩展strtok的分隔符范围
将\n和\r也加入strtok的分隔符集合,即使行内残留换行符,也不会干扰token解析:
token = strtok(line, " \n\r"); // 空格、\n、\r均作为分隔符
3. 跳过无效空行
如果换行符问题导致读取到空行(比如单独的\r或\n被读成空内容),直接跳过这类无效行,避免checkToken处理空指针:
while (rowCount < n && fgets(line, MAXLINE, stdin)) { // 清理行尾换行符 size_t len = strlen(line); if (len > 0) { if (line[len-1] == '\n') { line[len-1] = '\0'; if (len > 1 && line[len-2] == '\r') { line[len-2] = '\0'; } } else if (line[len-1] == '\r') { line[len-1] = '\0'; } } // 跳过空行 if (strlen(line) == 0) { continue; } token = strtok(line, " \n\r"); checkToken(token, n); // do something rowCount++; }
以上修改后,代码可兼容不同系统的换行符格式,在Visual Studio和Xcode中都能正常运行。
内容的提问来源于stack exchange,提问作者Tiehan Jiang
相关产品推荐
相关产品推荐

