首页 > 解决方案 > fscanf 在我的代码中扫描了多少个字符?

问题描述

我正在使用一个 for 循环,我想迭代的次数等于 scanf 扫描的字符数。但是,它似乎运行了太多次。该代码最初是为了打印成短语“我们在 2019 年”而编写的,它确实如此,但现在我需要将它用于其他事情。我在行中添加: printf("%i",i);

查看它经历了多少次 for 循环。无论扫描的单词有多长,每次运行 while 循环似乎都会运行 8 次。

#include <stdio.h>
#include <stdlib.h>

int main() {
    char* word = malloc(sizeof(char) * (46)); // create a char array

    FILE* fp;

    fp = fopen("file.txt", "w+");
    fputs("We are in 2019", fp);

    rewind(fp); // sets to start of file

    while(fscanf(fp, "%s", word) != EOF) {
        for(int i = 0; i < sizeof(word) / sizeof(word[0]); i++) {
            printf("%c", word[i]);

            printf("%i", i);
        }
        printf("\n");
    }

    fclose(fp);

    return (0);
}

输出是:

W0e1234567
a0r1e234567
i0n1234567
200112934567

所以我可以看到它每次运行 for 循环运行 8 次 while 循环的每次运行。

我是否误解了 fscanf 的工作原理?我以为它停在一个空白处,只存储前面的字符......例如,首先它会扫描“我们”,然后将其存储为“单词”中的 3 个字符数组,然后扫描“是”中的 4 个字符数组“词”等。到底发生了什么?

标签: c

解决方案


可以对您的代码进行几项注释

  • 根据定义sizeof(char)为 1,因此您malloc(sizeof(char) * (46))可以简化为malloc(46). 请注意,您也可以使用数组char word[46];

  • fscanf(fp, "%s", word)是非常危险的,如果读取的单词超过 45 个字符,你用未定义的行为写出单词,限制大小做fscanf(fp, "%45s", word)

  • 如备注中所说sizeof(word) / sizeof(word[0]),不返回您的单词长度,您可以在word[i]为 0时停止

  • 在每个字符之后打印索引不会产生非常可读的结果,您确定要这样做吗?

  • 为什么不直接通过(f)putsprintf以%s格式打印单词并使用strlen获取字符串的长度(如果您想知道的话)?

我想迭代的次数等于scanf扫描的字符数。

scanf扫描的字符数超过了字符串中返回的字符数,空格被静默绕过。只有一件事可以确定,当您到达文件末尾且没有错误时,scanf扫描的字符数(如果文件大小)。


推荐阅读