如何从文本文件中写入和读取(包括空格)
我正在使用fscanf
和fprintf
。
我尝试用\t
分隔每行的字符串,并像这样读取它:
fscanf(fp,"%d\t%s\t%s",&t->num,&t->string1,&t->string2);
文件内容:
1[TAB]string1[TAB]some string[NEWLINE]
它没有正确读取。 如果我printf("%d %s %s",t->num,t->string1,t->string2)
我得到:
1 string1 some
我也得到这个编译警告:
warning: format specifies type 'char *' but the argument has type 'char (*)[15]' [-Wformat]
如何在不使用二进制r / w的情况下解决这个问题?
我猜测"some string"
的空格是问题所在。 使用%s
读取字符串的fscanf()
在第一个空白字符处停止。 要包含空格,请使用以下内容:
fscanf(fp, "%d\t%[^\n\t]\t%[^\n\t]", &t->num, &t->string1, &t->string2);
另请参阅fscanf()
和/或另一个StackOverflow线程 的参考页面, 读取C中以制表符分隔的项目 。
[编辑响应您的编辑:您似乎也遇到了传递给fscanf()
的参数的问题。 您需要发布t->string1
的声明以确定,但看起来string1
是一个字符数组,因此您应该从fscanf()
调用中删除&
…
%s
转换规范在第一个空格处停止读取,制表符和空格都计为空白区域。
如果要读取一系列非选项卡,可以使用“扫描设置”转换说明符:
if (fscanf(fp, "%d\t%[^\t\n]\t%[^\t\n]", &t->num, t->string1, t->string2) != 3) ...oops - format error in input data...
(我遗憾的是&
从字符串参数中省略&
是正确的。) 问题已被编辑; 我赢了。 删除&
是必要的,以避免编译器警告!
这仍然不是你所期望的。 如果第二个字段的开头有空格,它们将被格式字符串中的\t
吃掉。 格式字符串中的任何空格都会占用输入中的任何空白区域(包括换行符)。 在输入中没有空格的字符之前, %[^\t]
转换规范才会开始。 我也假设你希望你的输入受到换行限制。 如果您愿意,可以省略\n
字符。
请注意,我检查了fscanf()
解释了3个字段。 错误检查您的输入很重要。
如果你真的想要控制,你应该用fgets()
读取整行,然后使用sscanf()
来解析数据。
关于
fgets()
和sscanf()
; 你能扩展一下它将如何提供更多控制吗?
假设输入数据已写入
1234 a string with spaces another string
像这样分散在多条线上。 使用原始fscanf()
,这将是可接受的输入,即使它分布在9行输入上。 使用fgets()
,您可以读取一行,然后使用sscanf()
进行分析,并且您将知道第一行的格式不正确。 然后,您可以决定如何处理它。
此外,由于mafso在评论中给我打电话,我们应该通过限制扫描设置匹配的字符串大小来确保没有缓冲区溢出。
if (fscanf(fp, "%d\t%14[^\t\n]\t%14[^\t\n]", &t->num, t->string1, t->string2) != 3) ...oops - format error in input data...
我正在使用关于char (*)[15]
的错误消息来推断14是正确的数字。 请注意,与printf()
不同,您不能通过*
表示法指定大小(在scanf()
家庭, *
压缩分配中),因此您必须创建具有正确大小的格式。 此外,您指定的大小是终止空字节之前的字符数,因此如果数组大小为15,则您在格式字符串中指定的大小为14,如图所示。