C ++ fscanf()返回-1并且不会覆盖变量

时间:2016-02-20 09:45:48

标签: c++ pointers scanf

我试图在C ++中创建一个从version读取File.txt的程序,如果数字正确(CORRECT VERSIONINCORRECT VERSION)则输出。我在Mac上使用Eclipse。

下面你可以看到我的程序。

#include <iostream>

int main() {
  FILE *pFile;
  pFile = fopen("./Desktop/File.txt", "a+");
  int version = 0, result = 0;
  int *pointer = &version;
  result = fscanf(pFile, "%d", pointer);
  if (version == 1)
    fprintf(pFile, "CORRECT VERSION");
  else
    fprintf(pFile, "INCORRECT VERSION - %d, %d", version, result);
  fclose(pFile);

  return 0;
}

File.txt之前......

1

之后...

1INCORRECT VERSION - 0, -1

我在互联网和stackoverflow.com上搜索过,我发现了其他一些讨论(fscanf() filterStopping fscanf?fscanf csv in C. Value not assigned)。我尝试了所有这些,但都没有奏效。任何帮助表示赞赏。 (顺便说一下,这是我的第一篇文章。)

亚当

编辑:

@FrankPuffer我尝试将a+替换为r+中的line 5,即使我不明白为什么也会有效,因为我非常确定a+之间的唯一区别{1}}和r+是:

  • 如果文件不存在,a+会创建该文件而r+会返回错误
  • 如果输出到文件a+最后写入,r+替换整个文件

2 个答案:

答案 0 :(得分:2)

`

`FWIW,这对我有用:

#include <cstdio>
#include <system_error>

int main() {
    FILE *pFile;
    pFile = fopen("/tmp/file.txt", "a+");
    if (!pFile) {
        throw std::system_error(errno, std::system_category());
    }
    int version = 0;
    int result;
    result = fscanf(pFile, "%d", &version);
    if (!result) {
        throw std::system_error(errno, std::system_category());
    }
    if (version == 1)
        fprintf(pFile, "CORRECT VERSION");
    else
        fprintf(pFile, "INCORRECT VERSION - %d, %d", version, result);
    fclose(pFile);

    return 0;
}

答案 1 :(得分:0)

如上所述here,scanf返回

  

成功分配的接收参数数量,或者EOF if   读取失败发生在分配第一个接收参数之前。

在您的示例中,它返回-1(大多数环境中的EOF),因此它不会更改版本(0)的值,这解释了&#34;不正确的&#34;打印。我无法使用包含单个1(似乎是您的情况)或1后跟换行符的文件重现该输出,但要使您的程序&#34;工作&#34 ;无论如何我添加了这一行:

fseek(pFile,0,SEEK_END);

在最终的if语句之前

if (version == 1)

顺便说一句,如果C++标记不对(并且您确实包含<iostream>),则应使用流:

#include <iostream>
#include <fstream>

using std::cerr;

const int version_needed = 1;

int main() {

    std::fstream file{"File.txt", std::ios::in | std::ios::out };   
    if ( file.bad() ) {
        cerr << "Sorry, can't open file.\n";
        exit(-1);
    }

    int version;
    file >> version;
    if ( file.fail() ) {
        cerr << "Error: can't read an int from file.\n"
             << "Unable to retrieve version number.\n";
        exit(-1);
    }
    // set state bit to good, you may have reach EOF while reading, but now
    // you want to write on the file
    file.clear();
    // set output position to the end of file. It should be there, anyway
    file.seekp(0, std::ios_base::end);
    if ( version == version_needed )
        file << "CORRECT VERSION";
    else
        file << "INCORRECT VERSION - " << version << " instead of " << version_needed;

    return 0;
}