我是否错误地使用了fscanf函数?

3

我在使用fscanf读取文本文件时遇到了小问题。

这是我的一小段C++代码:

struct tooted
{
    char nimi[50];
    int kogus;
    float hind;
}toode[20];

int main()
{
    FILE *kala;
    kala = fopen("kala.txt", "r");
    int i=0, n=0;
    char buffer[200];

    while(!feof(kala))
    {
        if(n<1)
        {
            fgets(buffer, 200, kala);
        }
        if(n>0)
        {
            fscanf(kala, "%s[^\t]%i[^\t]%f", toode[i].nimi, toode[i].kogus, toode[i].hind);
            i++;
        }
        n++;
    }

    for(i=0; i<n-1; i++)
    {
        printf("Toode: %s\nKogus: %i\n Hind: %f\n\n", toode[i].nimi, toode[i].kogus, toode[i].hind);
    }

    return 0;
}

fgets(buffer, 200, kala); 是为了从第二行开始使用 fscanf 函数。 在文件 kala.txt 中,我有三行数据,每行用 [tab] 分隔。第一个单词是字符串,第二个是整数,第三个是浮点数,格式如下:

product1 (tab) 4 (tab) 1.4
product2 (tab) 3 (tab) 2.3

它使用仅有的toode[i].nimi逐个读取单词(和数字),因此结果如下:

Toode: product1
Kogus: 0
Hind: 0.0000

Toode: 4
Kogus: 0
Hind: 0.0000

注意,product1可能是两个单词,但它们之间用的是空格而不是制表符。我希望它作为一个字符串来读取。

(在问问题之前我试图查找解决方案,但我找不到。如果这是一个重贴,请原谅。)

谢谢 :)


1
“int main()” 是整个问题中唯一的 C++。 - user657267
1
如果你要写C++,那么你应该*真正地写C++*。换句话说,使用std::stringstd::vectoriostreams等等。 - crashmstr
1
注意事项:1)不要错误地使用feof(kala),而是测试fscanf()的结果。2)在循环之前使用fgets(buffer, 200, kala); - chux - Reinstate Monica
甚至比使用 fgets 更好的方法是丢弃整个第一行。 - M.M
@crasstr 我相信你有权利用自己的风格编写代码。 - SwiftMango
3个回答

2

是的。你使用它的方式不对。

所有参数都必须是指针,你给了char[]的指针但没有给int和float的指针。

在C语言中,指针是创建输出(而不是返回)参数的唯一方法。格式后面的所有参数都是输出参数。

应该是这样的:(注意添加'&')

编辑我也修复了格式...

fscanf(kala, "%[^\t] %i %f", toode[i].nimi, &toode[i].kogus, &toode[i].hind);

谢谢您的澄清!我已经修复了我的代码。但是,它仍然没有解决主要问题。仍然无法扫描数据到“&toode[i].kogus”和“&toode[i].hind”。 - karu
1
你还应该测试fscanf的结果来控制实际读取的参数数量。 - Serge Ballesta
我找到了一个解决方案和主要问题。在文本文件中,我有逗号。这是一个大错误。谢谢大家的帮助 :) 我会尽快发布更长的答案(还需要8个小时,因为我的声誉还不到10) - karu

2

格式字符串中的"[^"会尝试匹配输入中的文字[^(可能失败),因为它前面没有%,所以不是scanf模式。你可能只需要:

fscanf(kala, " %[^\t]%i%f", toode[i].nimi, &toode[i].kogus, &toode[i].hind);

你还有很多其他问题,比如使用feof,而没有进行任何错误检查,但这至少可以让你开始。


0

好的,我稍微调试了一下,发现(还在学习)我不应该在文本文件中加逗号来获取信息。或者至少我应该让fscanf忽略逗号。

我也删除了[^\t],因为fscanf会像忽略空格一样忽略它们。

我的代码现在是:

struct tooted
{
    char nimi[50];
    int kogus;
    float hind;
}toode[20];

int main()
{
    FILE *kala;
    kala = fopen("kala.txt", "r");
    int i=0, n=0;
    char buffer[200], *token;

    fgets(buffer, 200, kala);
    while(!feof(kala))
    {
            fscanf(kala, "%s %i %f", toode[i].nimi, &toode[i].kogus, &toode[i].hind);
            printf("Toode: %s\nKogus: %i\n Hind: %2.2f\n\n", toode[i].nimi, toode[i].kogus, toode[i].hind);
            i++;
    }
    return 0;
}

我的输出现在是:

Toode: product1
Kogus: 1
Hind: 1.5

Toode: product2
Kogus: 2
Hind: 2.6

等一下,要翻譯成中文的程式相關內容只有以下這些:

就像我想要的那樣。

我知道我還沒有錯誤檢查,但那不是我試圖修復的錯誤,至少目前還不是。 對於沒有指定我的文字文件,沒有幫助你發現問題而感到抱歉。我不知道應該在那裡尋找問題 :)

我仔細研究了如何正確使用feof,你是對的,我可以做得更好以消除未來的錯誤。謝謝你的提醒(不確定是否正確使用這個表達方式 :P)。現在我只是沒有時間去修復它。

感謝大家的幫助:)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接