Предупреждения, связанные с чтением файла в массив символов в C - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть код, который компилирует и печатает данные из файла, но он заполнен предупреждениями, и я не могу их исправить.

void batchMode(char **c) {

     char *batchBuffer = NULL;
     size_t batchSize = 0;

     FILE *fp = fopen(c, "r");

     fseek(fp, 0, SEEK_END);
     batchSize = ftell(fp);

     rewind(fp);

     batchBuffer = malloc((batchSize + 1) * sizeof(*batchBuffer));

     fread(batchBuffer, batchsize, 1, fp);

     batchBuffer[batchSize] = 0;

     printf("%s\n", batchBuffer);

}

int main(int argc, char **argv){

    if (argc == 2)
          batchMode(&argv[1][0]);

     return 0;

}

Предупреждения включают в себя: передачу аргумента 1 пакетного режима из несовместимого типа указателя

batchMode (& argv [1] [0]);

ожидаемый 'char **' но аргумент имеет тип char *

void batchMode (char **c)

передача аргумента 1 fopen из несовместимого типа указателя

FILE * fp = fopen ( c, "r");

ожидается 'const char * restrict', но аргумент имеет тип char **

FILE * fopen (const char * _restrict_filename

Ответы [ 2 ]

1 голос
/ 04 февраля 2020
  • Возможно, вы захотите изменить сигнатуру метода batchMode, чтобы использовать указатель символа вместо указателя на указатель.
  • Соответственно, вы должны адаптировать вызов функции к batchMode(argv[1]);, чтобы передать первый программный аргумент в качестве параметра
  • второй параметр fread должен быть batchSize вместо batchsize (обратите внимание на заглавную S)
  • , так как batchBuffer выделяется динамически, вы должны добавить free (batchBuffer); после того, как он больше не нужен

Так что ваш слегка измененный код может выглядеть так:

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


void batchMode(const char *c) {
    char *batchBuffer = NULL;
    size_t batchSize = 0;
    FILE *fp = fopen(c, "r");
    fseek(fp, 0, SEEK_END);
    batchSize = ftell(fp);
    rewind(fp);

    batchBuffer = malloc((batchSize + 1) * sizeof(*batchBuffer));

    fread(batchBuffer, batchSize, 1, fp);

    batchBuffer[batchSize] = 0;

    printf("%s\n", batchBuffer);

    free(batchBuffer);
}

int main(int argc, char **argv) {
    if (argc == 2)
        batchMode(argv[1]);

    return 0;
}
0 голосов
/ 05 февраля 2020

следующие предложенные изменения в коде OP:

  1. безупречная компиляция
  2. выполняет желаемую функциональность
  3. правильно проверяет ошибки
  4. правильно Освободите выделенную память, когда закончите с этим

Примечание: функция: 'perror ()' передает сообщение об ошибке и текстовую причину, по которой система считает, что последний сбой произошел, в 'stderr'

А теперь предложенные изменения, с комментариями

#include <stdio.h>     //<-- missing
#include <stdlib.h>    //<-- missing


//void batchMode(char **c) {        //<-- needs pointer to a string, not a single character
         //<-- suggest using meaningful name, like: 'filename'
void batchMode( char *fileName ) {

     //char *batchBuffer = NULL;    //<-- limit scope and keep with 'setter'
     //size_t batchSize = 0;       //<-- ftell() returns a 'long', not a unsigned long
     //long batchSize = 0;         //<-- limit scope and keep with 'setter'

     FILE *fp = fopen( fileName, "r");        //<-- check returned value for success (!=NULL)
     if( ! fp )
     {
         perror( "fopen failed" );
         exit( EXIT_FAILURE );
     }

     //fseek(fp, 0, SEEK_END);         //<-- returns an 'int', check for success (!=-1)
      long batchSize;
     if( (batchSize = fseek( fp, 0, SEEK_END )) == -1 )
     {
         perror( "fseek for end of file failed" );
         exit( EXIT_FAILURE );
     }

     batchSize = ftell(fp);               //<-- check the returned value for an error indication (-1)
                                     //<-- returns a 'long', not a 'unsigned long'
     if( batchSize == -1 )
     {
         perror( "ftell failed" );
         exit( EXIT_FAILURE );
     }

     rewind(fp);                   //<-- does not have error checking, suggest: using 'fseek(fp, 0, SEEK_SET )'

    // batchBuffer = malloc((batchSize + 1) * sizeof(*batchBuffer));  //<-- 'sizeof(*batchBuffer)' is the size of a char pointer 4 or 8 depending on the underlying hardware architecture and certain compile options
                                         //<-- check for success, returned value (!=NULL)
     char * batchBuffer = malloc( (size_t)batchSize+1);
     if( ! batchBuffer )
     {
         perror( "malloc failed" );
         exit( EXIT_FAILURE );
     }

     //fread(batchBuffer, batchsize, 1, fp);   // incorrect capitalization of batchSize
     if( fread(batchBuffer, (size_t)batchSize, 1, fp) != 1 )    //<-- if returned value != third parameter, then error occurred
     {
         perror( "fread failed" );
         exit( EXIT_FAILURE );
     }

     batchBuffer[batchSize] = 0;

     printf("%s\n", batchBuffer);

     free( batchBuffer );      //<-- to avoid memory leak
}


int main(int argc, char **argv){

     //if (argc == 2)               //<--  handle error first
     if( argc != 2 )
     {
         fprintf( stderr, "USAGE: %s <fileName>\n", argv[0] );
         exit( EXIT_FAILURE );
     }

     //batchMode(&argv[1][0]);   //<-- send pointer to first command line parameter, not a single character
     batchMode( argv[1] );

     return 0;
}
...