Ошибки при передаче char в функции - PullRequest
0 голосов
/ 15 марта 2020

Я пытаюсь передать символ в функцию, но получаю ошибки при этом. Это основная функция, которую у меня есть

#include "maiello8_headers_P1.h"

int main()
{
        int characterCount;
        int wordCount;
        int lineCount;
        char fileName[20];

        printf("Enter the name of the text file: ");
        scanf("%s\n",fileName);


        characterCount = countCharacters(fileName);
        wordCount = countWords(fileName);
        lineCount = countLines(fileName);

        printf("Characters: %d\n", characterCount);
        printf("Words: %d\n", wordCount);
        printf("Lines: %d\n", lineCount);

        return 0;
}

Я получаю ошибку:

maiello8_main_P1.c: In function ‘main’:
maiello8_main_P1.c:20:35: warning: passing argument 1 of ‘countCharacters’ makes integer from pointer without a cast [-Wint-conversion]
   20 |  characterCount = countCharacters(fileName);
      |                                   ^~~~~~~~
      |                                   |
      |                                   char *
In file included from maiello8_main_P1.c:9:
maiello8_headers_P1.h:8:26: note: expected ‘char’ but argument is of type ‘char *’
    8 | int countCharacters(char fileName);
      |                     ~~~~~^~~~~~~~

Но когда я меняю программу на characterCount = countCharacters (char fileName) ; или characterCount = countCharacters (char fileName); Я получаю сообщение об ошибке «ожидаемое выражение перед символом. Поэтому я не уверен, что проблема в основной функции функции countCharacters. Это функция countCharacters

#include "maiello8_headers_P1.h"

int countCharacters(char fileName)
{
        char currentCharacter;                      
        int numCharacters = 0;                      
        FILE *fpt;                          
        fpt = fopen(fileName,"r");                  

        while((currentCharacter = fgetc(fileName)) != EOF)      
        {
                if(currentCharacter != ' ' && currentCharacter != '\n') 
                        numCharacter++;                 

        }
        fclose(fileName);                       

        return numCharacter;                        
}

Я использую Makefile для этого». поэтому проблема также может быть в заголовке:

#ifndef pH
#define pH

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

int countCharacters(char fileName);
int countWords(char fileName);
int countLines(char fileName);

#endif

Прошу прощения за то, что выложил так много кода, но я новичок в C и уже часами смотрю на подобное проблемы и не могут найти решение.

1 Ответ

1 голос
/ 15 марта 2020

filename неудивительно, что это «строка», то есть массив символов:

char fileName[20];

(Это очень мало места для имени файла, не так ли? имя, maiello8_headers_P1.h, имеет длину 21 символ, поэтому для него потребуется не менее 22 символов в массиве, и это предполагает, что вы никогда не добавите путь к каталогу. Будьте немного более щедрыми. У вас есть несколько миллиардов байт памяти на вашем компьютере ; резервирование нескольких тысяч для пути к файлу не сломает банк :-) Но я отвлекся.)

В C вы не можете фактически передавать массивы в качестве параметров. Вы должны передать указатель на первый элемент. Компилятор поможет вам в этом, автоматически изменив аргумент массива на указатель на первый элемент в массиве. Это называется «распад», термин, с которым вы столкнетесь рано или поздно.

Итак, ваши функции вызываются с указателем на первый элемент в filename. Этот элемент является char, поэтому тип потерянного аргумента - char *. Но ваш заголовок объявляет:

int countCharacters(char fileName);

Другими словами, заголовок говорит, что аргумент countCharacters является одним символом.

Когда вы объявляете функцию, C верит в то, что ты говоришь. Поэтому ожидается, что вы вызовете функцию с одним символом. В C символы - это просто маленькие целые числа, и маленькое целое число, безусловно, не то, чего должна ожидать ваша функция. Таким образом, компилятор пытается уменьшить указатель на первый символ в filename в маленькое целое число, отбрасывая все, кроме последнего байта значения указателя. Поскольку это почти наверняка не то, что вы хотели, компилятор предупреждает вас о том, что вы, вероятно, делаете что-то отличное от того, что, как вы думали, вы делаете.

Вы получаете полный балл за запрос предупреждений компилятора (если вы их запрашивали, скорее чем получить Makefile, который сделал это для вас. Компиляторы не обязаны предупреждать вас о подобных вещах, которые на самом деле являются законными C, даже если они не имеют смысла, а G CC не будет выдавать предупреждения если вы не попросите это явно. Это одна из немногих уступок человеческой слабости, которую вы найдете в компиляторе C, и лучше всего использовать ее в полной мере.

Короче, исправьте объявление ваших функций, оба в заголовочном файле. и в файле реализации. Хороший выбор -

int countCharacters(const char* fileName);

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...