读取String中的fscanf问题

jum*_*umm 5 c scanf

我正在读一个.txt文件.我正在使用fscanf来获取格式化的数据.我遇到问题的这条线是这样的:

result = fscanf(fp, "%s", ap->name);
Run Code Online (Sandbox Code Playgroud)

这是好的,直到我有一个空格的名称,例如:St Ives所以我用这个来读取空白区域:

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

但是,当我尝试读取第一个名称(没有空白区域)时,它只是不起作用并且弄乱了其他的fscanf.

但我使用[^ \n]它在我正在使用的不同文件中工作正常.不确定发生了什么.

如果我在fscanf的位置使用fgets,我会在变量中得到"\n".

编辑//

好的,所以如果我使用:

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

这允许我读入没有空格的字符串.但是当我得到一个带有空格的"名字"时它不起作用.

Ada*_*eld 12

这有一个问题:

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

s你的格式说明符末尾有一个额外的.整个格式说明符应该是%[^\n],它表示"读入一个字符串,该字符串由不是换行符的字符组成".额外s不是格式说明符的一部分,因此它被解释为文字:"从输入中读取下一个字符;如果它是"s",则继续,否则失败."

但是额外的内容s实际上并没有伤害到你.您确切知道输入的下一个字符:换行符.它不匹配,输入处理在那里停止,但它并不重要,因为它是格式说明符的结尾.但是,如果在同一格式字符串之后有其他格式说明符,则会导致问题.

真正的问题是你没有使用换行符:你只读取换行符之前的所有字符,而不是换行符本身.要解决这个问题,你应该这样做:

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

%*c说明符说,读一个字符(c),但不要把它分配给任何变量(*).如果省略了*,则必须传递fscanf()包含指向字符(a char*)的指针的另一个参数,然后它将存储它读入的结果字符.

你也可以使用%[^\n]\n,但也可以在新行后面的任何空格中读取,这可能不是你想要的.当fscanf在其格式说明符(空格,换行符或制表符)中找到空格时,它会消耗尽可能多的空格(即,您可以认为它消耗了与正则表达式匹配的最长字符串[ \t\n]*).

最后,您还应指定最大长度以避免缓冲区溢出.您可以通过将缓冲区长度放在%和之间来实现[.例如,如果ap->name是256个字符的缓冲区,则应该这样做:

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

这适用于静态分配的数组; 遗憾的是,如果数组在运行时具有动态大小,那么传递缓冲区大小并不容易fscanf.你必须创建格式字符串sprintf,例如:

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


小智 0

我不确定你的意思 [^\n] 应该如何工作。[] 是一个修饰符,表示“接受一个字符,但该块内的任何字符除外”。反转^条件。带有 fscanf 的 %s 仅读取,直到遇到分隔符。对于包含空格和换行符的字符串,请使用 fgets 和 sscanf 的组合,并指定长度限制。