unix环境中的C语言-Fscanf和sprint命令
我正在尝试读取分隔符为“tab”的30行5列的文件。每次我只得到部分行。 在windows环境中,它运行良好。知道为什么在unix中它不工作吗unix环境中的C语言-Fscanf和sprint命令,c,unix,printf,scanf,C,Unix,Printf,Scanf,我正在尝试读取分隔符为“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) {
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
返回成功读取的项目数。
此计数可以与预期数字匹配,如果匹配失败,则可以小于预期数字
您应该检查
fscanf
s返回值以查看哪一行未正确解析,并检查输入数据。fscanf()字符串中的\t字符不是必需的-制表符是空白,因此您可以说“%s%s%s”-可以想象,两个scanf实现对它们的处理方式不同。此外,您应该检查fscanf是否返回除EOF以外的值,但不等于预期的转换次数,这表明存在某种类型的转换错误。更仔细地检查fscanf()
中的返回值;例如,如果它匹配3个字段,它将返回3。您可能需要注意各种字符串的大小,以避免缓冲区溢出——不过,这可能是另一天的主题
让我印象深刻的可能是,格式字符串中的最后一个制表符作为换行符可能更好—但是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;
}
#包括
内部主(空)
{
字符b1[20]、b2[20]、b3[20]、b4[20]、b5[20];
而(fscanf(stdin,“%s\t%s\t%s\t%s\t”,b1、b2、b3、b4、b5)=5)
printf(“%s\t%s\t%s\t%s\t%s\t%s\n”,b1、b2、b3、b4、b5);
返回0;
}
然而,它确实将字符串“k
”(5个单字母用空格分隔)视为等同于5个制表符分隔。因此,问题在于C标准第§7.19.6.2节规定:
该格式由零个或多个指令组成:一个或多个空白
字符、普通多字节字符(既不是%也不是空白字符)或
转换规范
将跳过输入的空白字符(由isspace函数指定),除非
该规范包括[、c或n说明符
另外,关于“%s”说明符,它表示:
匹配一系列非空白字符
要强制匹配实际制表符,您必须更加努力。使用“将行读入缓冲区(
fgets()
)并手动拆分”会更容易。这还允许您在一行上强制执行5个字,如果字段太少或太多,您可以生成错误或警告。使用fscanf()
,您不能这样做。如果您在一行中键入8个单词,它将第一次读取前5个单词,然后在这行中读取剩余的3个单词,再加上下一行中的前两个单词,依此类推。您能发布一个示例行并告诉我们读取了多少吗?您使用的是完全相同的文件吗?Windows/Unix选项卡的解释可能不同。可能,当复制到unix时,在windows上使用制表符创建的文件可能不符合预期。@Gunner-你确定你没有将制表符与行尾标记混淆吗?我同意。当然制表符的\t
是通用的吗?不要像前面所说的那样,将格式字符串中的\n
与\r
n`空格混淆,例如\t,将t中的空格清空输入,如\t和\r和\n以及空格。此程序使用\t是模糊但有效的。“您不妨说”%s%s%s”“--不,即使我们将您的键入错误修复为“%s%s%s%s”(五个字符串而不是4个字符串),它仍然不能作为替代。但是用“%s%s%s%s\t”清除尾随空白将是一种替代方法。