从C中的文件逐行读取

时间:2014-05-29 21:03:56

标签: c file io

我要做的是逐行打印文件的内容。我在终端中运行程序:./ test testText.txt。当我这样做时,打印出随机字符,但不打印文件中的内容。文本文件与makefile位于同一文件夹中。怎么了?

#include <stdio.h>

FILE *fp;
int main(int argc, char *argv[])
{


char line[15];
fp = fopen(*argv, "r");

while((fgets(line, 15, fp)) != NULL)
    {
        printf(line);
        printf("\n");
    }


}

4 个答案:

答案 0 :(得分:1)

  

当我这样做时,会打印出随机字符,但不打印文件中的内容

这些字符随机,实际上它们来自文件。但是,这不是您尝试阅读的文件 - 它是您正在运行的可执行文件。

*argv表示可执行文件的名称;添加此行以查看*argv中的内容:

printf("%s\n", *argv);

实际的命令行参数从argv[1]开始,因此您需要

fp = fopen(argv[1], "r");

答案 1 :(得分:1)

在命令行上传递的第一个参数位于argv[1],而*argv指的是argv[0]argv[0]包含可执行文件的文件名 - 您正在打印可执行文件的内容。

以下代码打印出整个argv[]数组,然后读取您的文件并打印出来。

#include <stdio.h>

int main( int argc, char *argv[] )
{
    for( int i = 0; i < argc; i++ )
    {
        printf( "argv[%d] : %s\n", i, argv[i] ) ; 
    }

    if( argc >= 2 )
    {
        FILE* fp = fopen( argv[1], "r" ) ;
        if( fp != NULL )
        {
            char line[15];

            while( fgets( line, sizeof(line), fp ) != NULL )
            {
                printf( "%s", line ) ;
            }
        }
    }

    return 0 ;
}

请注意,fgets()会读取包含该行的整行,因此无需打印&#39; \ n&#39;,特别是因为只有15个字符,您的行缓冲区可能不包含整条线。还要注意变量的更紧密的本地化 - 你的代码不必要地使fp 全局

其他改进是安全使用数组大小​​而不是文字15,并使用文字常量字符串作为格式说明符。您应该避免为printf()格式字符串传递变量字符串 - 如果您的输入本身包含格式说明符,printf()将尝试从不存在未定义结果的参数中读取数据。

答案 2 :(得分:1)

问:出了什么问题?

谦虚的批评:

#include <stdio.h>

FILE *fp; // Perhaps this should be declared inside main?

int main(int argc, char *argv[])
   {
   char line[15]; // Are the file lines all 14 characters or less?  (seems small)

   fp = fopen(*argv, "r"); // Opening the binary executable file (argv[0])? Intereting.
   // Should check here to ensure that fopen() succeeded.      

   while((fgets(line, 15, fp)) != NULL)

好的......好吧,请记住,这不是text文件..它是可执行文件(由于*argv)。这将从可执行文件中读取一些古怪的(但非随机)字符。

      {
      printf(line);  // Bad practice.  Should be: printf("%s", line);

好的......现在打印古怪的人物?

      printf("\n");  // Redundant. The '\n' characters will be supplied in 'line'.
      }

   // fclose() call missing.

   // Integer return value for main() is missing.
   }

这可能是(或许)实际意图:

#include <stdio.h>
#include <errno.h>

int main(int argc, char *argv[])
   {
   int rCode = 0;
   FILE *fp = NULL;
   char line[255+1];

   if(argc != 2)
     {
     printf("Usage: %s {filepath}\n", *argv);
     goto CLEANUP;
     }

   errno=0;
   fp = fopen(argv[1], "r");
   if(NULL == fp)
      {
      rCode=errno;
      fprintf(stderr, "fopen() failed. errno:%d\n", rCode);
      goto CLEANUP;
      }

   while(fgets(line, sizeof(line), fp))  /* --As per 'chux' comment */
      printf("%s", line);

 CLEANUP:

   if(fp)
      fclose(fp);

   return(rCode);
   }

或者,如果意图真的要打印可执行文件的内容,可能就是这样:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>

int main(int argc, char *argv[])
   {
   int rCode = 0;
   FILE *fp = NULL;
   off_t offset = 0;

   errno=0;
   fp = fopen(*argv, "r");
   if(NULL == fp)
      {
      rCode=errno;
      fprintf(stderr, "fopen() failed. errno:%d\n", rCode);
      goto CLEANUP;
      }

   for(;;)
     {
     char line[16];
     size_t bytesRead;
     int index;
     char ascii[16+1];

     memset(ascii, 0, sizeof(ascii));
     bytesRead = fread(line, 1, sizeof(line), fp);
     if(0==bytesRead)
        break;

     printf("   %08zX | ", offset);
     for(index=0; index < bytesRead; ++index)
        {
        printf("%02hhX%c", line[index], 7==index ? '-' : ' ');
        ascii[index] = isprint(line[index]) ? line[index] : '.';
        }

     printf("%*s   %s\n", (16 -index) * 3, "", ascii);
     offset += bytesRead;
     }

   if(errno)
      {
      rCode=errno;
      fprintf(stderr, "fgets() failed.  errno:%d\n", errno);
      }

CLEANUP:

   if(fp)
      fclose(fp);

   return(rCode);
   }

答案 3 :(得分:0)

您的文件名在argv的索引1处找到。

if (argc <= 1) {
    printf("no file was given\n");
    exit(-1);
}

// open file from argv[1]
// ...