Могу ли я передать строку в fopen ()? в с - PullRequest
0 голосов
/ 15 ноября 2010

Моя цель - собрать входные данные и открыть файлы на основе этих входных данных.

FILE* 
open_input_file (char* fileName) //opens source file to be read
{ 
 return fopen(fileName, "r");
}

В предыдущей функции я собираю данные от пользователя и сохраняю их в fileNameКогда я отлаживаю программу, она говорит мне, что fopen возвращает NULL.Это не то, что я хочу, и я не уверен, где проблема.

int main(void)
{    FILE* inFile = NULL;
     char infileName[32] = {'\0'};
     gather_input(infileName); // infileName is an output parameter for this
     inFile = open_input_file(infileName);
}

Я не знаю, в чем проблема.Есть мысли?

Ответы [ 3 ]

2 голосов
/ 15 ноября 2010

Если fopen возвращает NULL, открытие не удалось. errno будет содержать код ошибки , а strerror(errno) вернет краткое описание причины сбоя при открытии.

#include <errno.h>
#include <string.h>

...

int main(void)
{    FILE* inFile = NULL;
     char infileName[32] = {'\0'};
     gather_input(infileName); // infileName is an output parameter for this
     if (!(inFile = open_input_file(infileName))) {
         fprintf(stderr, "Error opening '%s': %s\n", 
                 infileName, strerror(errno));
     } else {
         // open successful
         ...
     }
}

Off-тема

gather_input лучше убедиться, что infileName завершен нулем, чтобы предотвратить переполнение буфера. Самый простой способ сделать это - определить размер буфера имени файла в качестве макроса и установить последний символ равным 0.

#define FILENAMELEN 32
void gather_input(char infileName[]) {
    ...
    infileName[FILENAMELEN-1]=0;
}

 int main(void)
{    FILE* inFile = NULL;
     char infileName[FILENAMELEN] = {'\0'};

Это не очень гибко. Вместо этого вы можете передать размер буфера имени файла в gather_input.

#define LENGTH(a) (sizeof(a) / sizeof(a[0]))
void gather_input(char infileName[], size_t len) {
    ...
    infileName[len-1]=0;
}

 int main(void)
{    FILE* inFile = NULL;
     char infileName[32] = {'\0'};
     gather_input(infileName, LENGTH(infileName)); // infileName is an output parameter for this

Альтернативой установке последнего символа, если используются стандартные функции работы со строками, является использование функций strl* (strlcpy и strlcat), а не их неограниченных родственников. Если вы не используете strl*, вы должны использовать strncpy и strncat.

2 голосов
/ 15 ноября 2010
  1. Вы проверили, существует ли файл, на который указывает inFilename, на вашем жестком диске?

  2. Проверьте значение infileName в отладчике или поместите оператор printf впоказать значение на экране.printf ("'% s' \ n", infileName);

  3. Вы вызывали fclose () для своего файла в вызове open_input_file ().Может быть, файл все еще заблокирован?

Редактировать: Я только что проверил код.Я изменил вашу функцию english_to_morse ().1. За оператором while легче следовать, чем для .2. fgetc () возвращает int, а не char.

В начале инициализации я добавил это.Это инициализирует каждую строку в массиве с неопределенной строкой ". ??.".Это облегчит поиск странных ошибок, так как все в вашем массиве по крайней мере инициализировано.

Я изменил различные разделы кода, но вы должны быть в состоянии следовать.

    initialize_morse_alphanum (char morseStrings[91][6])
    {   
        for (int i=0;i<91;i++)
            strcpy(morseStrings[i], ".??.");

        ....
        ....



    void 
    english_to_morse(FILE* inputFile, FILE* outputFile, char morseStrings[91][6])
    {   int convert;

        convert = fgetc(inputFile);
        while (convert != EOF)
        {   
            fputs(morseStrings[convert], outputFile);
            fputc(' ', outputFile);
            printf ("%s ", morseStrings[convert]);
            convert = fgetc(inputFile);
        }
    }


open_output_file (char* fileName)  //opens destination file to be written
{   FILE* handle = NULL;
    handle = fopen (fileName, "w");    <---- Remove the * from filename
    return handle; }

Также, как упоминалось в другом ответе, было бы хорошо добавить некоторые проверки границ вразличные области кода.На данный момент он довольно подвержен сбоям.Если мой входной файл содержит строчную букву 'a' (ascii 96), ваша программа будет обращаться к памяти, которая находится за пределами.Таким образом, вы должны добавить где-то строку вроде if (convert> = '0' && convert <= 'Z').Я позволю тебе разобраться с этим. </p>

0 голосов
/ 15 ноября 2010

Убедитесь, что gather_input работает правильно. Может ли это быть проблемой, потому что вы пытаетесь прочитать файл, на котором вы также пишете? В этом случае попробуйте закрыть и снова открыть поток.

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