的fscanf问题与阅读的字符串 [英] fscanf problem with reading in String

查看:151
本文介绍了的fscanf问题与阅读的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读一个.txt文件。我使用的fscanf,因为它的格式来获取数据。
我有问题的线路是这样的:

I'm reading in a .txt file. I'm using fscanf to get the data as it is formatted. The line I'm having problems with is this:

result = fscanf(fp, "%s", ap->name);

这是罚款,直到我有一个空格如一个名字:圣艾夫斯
所以我用这个在白色空间为:

This is fine until I have a name with a whitespace eg: St Ives So I use this to read in the white space:

result = fscanf(fp, "%[^\n]s", ap->name);

然而,当我尝试的第一个名字读取(无空格),它只是不工作,打乱了对方的fscanf。

However, when I try to read in the first name (with no white space) it just doesn't work and messes up the other fscanf.

但我用的是[^ \\ n]的它我使用的是不同的文件中正常工作。不知道发生了什么。

But I use the [^\n] it works fine within a different file I'm using. Not sure what is happening.

如果我使用与fgets中的fscanf的地方上面我在变量得到\\ n。

If I use fgets in the place of the fscanf above I get "\n" in the variable.

编辑//

好了,如果我使用:

result = fscanf(fp, "%s", ap->name);
result = fscanf(fp, "%[^\n]s", ap->name);

这让我在没有空格的字符串读取。但是,当我得到一个名与空格这是行不通的。

This allows me to read in a string with no white space. But When I get a "name" with whitespace it doesn't work.

推荐答案

一个问题是:

result = fscanf(fp, "%[^\n]s", ap->name);

是您在您的格式说明的末尾有一个额外的取值。整个格式说明应该仅仅是%[^ \\ n] ,它说,其中包括不属于新行字符的字符串读。额外的取值不是格式说明符的一部分,所以它PTED作为文字间$ P $:从输入读取下一个字符;如果它是一个S继续,否则失败。

is that you have an extra s at the end of your format specifier. The entire format specifier should just be %[^\n], which says "read in a string which consists of characters which are not newlines". The extra s is not part of the format specifier, so it's interpreted as a literal: "read the next character from the input; if it's an "s", continue, otherwise fail."

额外的取值实际上不会伤害你,虽然。你确切地知道输入的下一个字符:换行。它不匹配,以及输入处理停止存在,但它其实并不重要,因为它是你的格式说明的结束。这会造成问题,但是,如果这一个相同的格式字符串后面有其他的格式说明。

The extra s doesn't actually hurt you, though. You know exactly what the next character of input: a newline. It doesn't match, and input processing stops there, but it doesn't really matter since it's the end of your format specifier. This would cause problems, though, if you had other format specifiers after this one in the same format string.

真正的问题是,你不消耗新行:你只中的所有字符读的换行,但不换行本身。为了解决这个问题,你应该这样做:

The real problem is that you're not consuming the newline: you're only reading in all of the characters up to the newline, but not the newline itself. To fix that, you should do this:

result = fscanf(fp, "%[^\n]%*c", ap->name);

%* C 说明说,在一个字符阅读( C ),但不分配它任何变量( * )。如果省略了 * ,你将不得不通过的fscanf()包含一个指向一个字符另一个参数( 的char * ),哪里会那么存储产生的字符,它的读取。

The %*c specifier says to read in a character (c), but don't assign it to any variable (*). If you omitted the *, you would have to pass fscanf() another parameter containing a pointer to a character (a char*), where it would then store the resulting character that it read in.

您也可以使用%[^ \\ n] \\ n ,但也将阅读随后的换行,你想要什么了不得的任何空白。当的fscanf 在格式说明符(空格,换行,或标签)发现的空白,它将消耗空白,因为它可以(即你可以消耗最长的字符串认为它,经常前pression匹配 [\\ t \\ n] * )。

You could also use %[^\n]\n, but that would also read in any whitespace which followed the newline, which may not be what you want. When fscanf finds whitespace in its format specifier (a space, newline, or tab), it consumes as much whitespace as it can (i.e. you can think of it consuming the longest string that matches the regular expression [ \t\n]*).

最后,您还应该指定一个最大长度,以避免缓冲区溢出。您可以通过将缓冲区长度在 [之间做到这一点。例如,如果 AP->名称为256个字符的缓冲区,你应该这样做:

Finally, you should also specify a maximum length to avoid buffer overruns. You can do this by placing the buffer length in between the % and the [. For example, if ap->name is a buffer of 256 characters, you should do this:

result = fscanf(fp, "%255[^\n]%*c", ap->name);

这伟大工程静态分配的数组;不幸的是,如果数组在运行时dyamically大小,有没有简单的方法来传递缓冲区大小的fscanf 。你必须创建格式字符串与的sprintf ,例如:

This works great for statically allocated arrays; unfortunately, if the array is dyamically sized at runtime, there's no easy to way to pass the buffer size to fscanf. You'll have to create the format string with sprintf, e.g.:

char format[256];
snprintf(format, sizeof(format), "%%%d[^\n]%%*c", buffer_size - 1);
result = fscanf(fp, format, ap->name);

这篇关于的fscanf问题与阅读的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆