C ++:fopen / fgets在读取XML文件

时间:2016-01-28 22:56:29

标签: c fopen fgets

我尝试读取XML文件(大小为29.3 MB)并使用小型C ++程序将内容打印到控制台。问题是它在文件中很早就停止了(甚至不是1%),我无法弄清楚原因。代码如下:

#include <stdio.h>

int main( int argc, char ** argv ) {
const char * fn = "countries.xml";          // file name
const static int maxString = 1024;  // read buffer size

// read the file
printf("reading file\n");
char buf[maxString];
FILE * fr = fopen(fn, "r");

int i;
for(i = 0; i < 20000; i++) {
    fgets(buf, maxString, fr);
    printf(buf);
}
fclose(fr);
printf("done.\n");

return 0;
}

编辑:这个for循环实际用于查看我之前的循环调节是否出现问题。实际上我的循环在哪里:

char * rc;
while(( rc = fgets(buf, maxString, fr) )) {
    printf(buf);
}

然而,无论我使用哪种形式的循环以及哪种条件(我可以使我尽可能高),它都会停止在XML文件中的同一点打印到控制台。

2 个答案:

答案 0 :(得分:4)

如果buf包含'%',则以下代码很容易导致未定义的行为。

printf()将其第一个扩充视为一种格式,并且可能希望跟随匹配的参数与"%s"等一起使用。当然,像"%S"这样的格式不正确的说明符会导致未定义的行为。

// bad
while (fgets(buf, maxString, fr)) {
  printf(buf);

使用fputs()

// good
while (fgets(buf, maxString, fr)) {
  fputs(buf, stdout);

答案 1 :(得分:0)

编译时,始终启用所有警告,然后修复这些警告。

至少使用gcc

-Wall -Wextra -pedantic

我也用:

-Wconversion -std=c99

编译器的输出显示代码中的几个问题(所有警告)。一般来说,绝不应忽视警告。

  1. 未使用的参数:argc
  2. 未使用的参数:argv[]
  3. 调用printf(),没有格式字符串文字,也没有格式说明符
  4. '静态'不在声明开始时。
  5. 然后循环方法有很多不足之处,

    1. 固定数量的循环
    2. 无法检查函数的返回值:fgets()
    3. 然后,在C中,创建一个静态const变量占用文件内存空间。 #define那个值

      要好得多

      为了便于我们人类理解和阅读,一致地缩进代码。

      1. 在每个左大括号{
      2. 之后缩进
      3. 在每个右大括号}
      4. 之前取消缩进

        缩进时,永远不要使用制表符,因为每个字处理器/编辑器的制表符/制表符宽度设置不同。

        建议每个级别的缩进使用4个空格,因为它足够宽,即使使用可变宽度字体也可以看到,并且允许在整个页面上有许多缩进级别的空间。

        调用许多/大多数系统函数时,需要检查返回的值以确保操作成功。

        #include <stdio.h>
        #include <stdlib.h> // exit(), EXIT_FAILURE
        
        #define MAX_STRING (1024)
        
        int main( void )
        {
            const char * fn = "countries.xml";          // file name
        
            // read the file
            printf("reading file\n");
            char buf[ MAX_STRING ];
        
            FILE * fr = NULL;
            if( NULL == ( fr = fopen(fn, "r") ) )
            { // then fopen failed
                perror( "fopen for read of countries.xml failed" );
                exit( EXIT_FAILURE );
            }
        
            // implied else, fopen successful
        
            while( fgets( buf, sizeof buf, fr ) )
            {
                printf("%s", buf);
            }
        
            fclose(fr);
            printf("done.\n");
        
            return 0;
        } // end function: main