繁体   English   中英

C语言 - unix环境中的Fscanf和sprint命令

[英]C language - Fscanf and sprint commands in unix environment

我正在尝试使用“tab”分隔符读取包含30行和5列的文件。 每次我只获得部分行。 在Windows环境中它运行良好。 知道为什么在unix中它不起作用?

while (fscanf(FFMapFile, "%s\t%s\t%s\t%s\t%s\t", fnfMap[i].COS_ID, fnfMap[i].FF_First_Act, fnfMap[i].FF_Next_Act, nfMap[i].Free_FF_allowed, fnfMap[i].FF_Change_Charge) != EOF)
{ 
    sprintf(s,"%s\t%s\t%s\t%s\t%s\t", nfMap[i].COS_ID, fnfMap[i].FF_First_Act, fnfMap[i].FF_Next_Act, fnfMap[i].Free_FF_allowed, fnfMap[i].FF_Change_Charge);
    error_log(s,ERROR);
    i++; }

你的fscanf()字符串中的\\ t字符不是必需的 - 制表符是空格,所以你也可以说“%s%s%s%s” - 可以想象,两个scanf实现对它们的处理方式不同。 此外,您应该检查fscanf返回EOF以外的值但不等于预期转换的数量,这表示某种转换错误。

成功时, fscanf返回成功读取的项目数。 此计数可以匹配预期的数量,或者在匹配失败的情况下更少。

您应该检查fscanf的返回值以查看未正确解析的行并检查输入数据。

更仔细地检查fscanf()的返回值; 例如,如果匹配3个字段,它将返回3。 您可能需要注意各种字符串的大小以避免缓冲区溢出 - 但是,这可能是另一天的主题。

令我fscanf()的可能性是格式字符串中的最后一个选项卡可能更好作为换行符 - 但fscanf()通常对格式字符串和数据中的空格采取相当自由的态度。

这个简化(但完整,有效)的代码版本在MacOS X上或多或少地表现得很好。

#include <stdio.h>

int main(void)
{
    char b1[20], b2[20], b3[20], b4[20], b5[20];
    while (fscanf(stdin,"%s\t%s\t%s\t%s\t%s\t", b1, b2, b3, b4, b5) == 5)
        printf("%s\t%s\t%s\t%s\t%s\n", b1, b2, b3, b4, b5);
    return 0;
}

但是,它确实将字符串' kkkkk '(由空格分隔的5个单个字母)视为等效,以5个制表符分隔。 因此,问题是C标准的第7.19.6.2节规定:

格式由零个或多个指令组成:一个或多个空格字符,普通的多字节字符(既不是%也不是空白字符),或转换规范。

除非规范包含[,c或n说明符,否则将跳过输入空白字符(由isspace函数指定)。

另外,关于'%s'说明符,它说:

匹配一系列非空白字符。

要强制匹配实际标签,您必须更加努力地工作。 求助于“将一行读入缓冲区( fgets() )并手动拆分”会更容易。 这也允许您在一行上强制执行5个单词,如果字段太少或太多,您可以生成错误或警告。 使用fscanf() ,你不能这样做。 如果你在一行上键入8个单词,它将在第一次读取前五个单词,然后在行上读取剩余的三个单词加上下一个单词的前两个单词,依此类推。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM