C язык - возвращение двумерного массива символов - PullRequest
1 голос
/ 04 апреля 2020

Я пытаюсь вернуть двумерный массив, но он на самом деле не присваивается переменной str. Может кто-нибудь сориентировать меня, что я делаю не так?

int main()
    {
        char** str = OpenFile();

    //reverseString(str);

   return 0;
}

char** OpenFile() {

    char line[HEIGHT][LENGTH];
    char *fname = "test.txt";
    FILE *fptr = NULL;
    int i = 0;

    fptr = fopen(fname, "r");
    while(fgets(line[i], LENGTH, fptr))
    {
        line[i][strlen(line[i]) - 1] = '\0';
        i++;
    }

    return line;
}

Ответы [ 3 ]

3 голосов
/ 04 апреля 2020
char line[HEIGHT][LENGTH];

Строка переменной массива [] [] объявлена ​​как локальная переменная в функции OpenFile (). Поэтому он выходит из области видимости, как только OpenFile () заканчивает выполнение. Вы можете объявить строку [] [] как глобальную или передать ее своей функции в качестве параметра.

0 голосов
/ 04 апреля 2020

Вы возвращаете локальную переменную, которая будет go вне области видимости, когда функция вернется.

Лучше передать массив, который вы хотите заполнить, в параметре функции:

Там также другие проблемы с вашим кодом, заменим код замены.

Работает пример ссылки

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

#define LENGTH 20
#define HEIGHT 10

void OpenFile(char line[][LENGTH]); //pass array as argument

int main()
{
    char line[HEIGHT][LENGTH];
    OpenFile(line);
    return 0;
}

void OpenFile(char line[][LENGTH]) // changes in 2D array will be permanent
{
    char *fname = "test.txt";
    FILE *fptr = NULL;
    int i = 0;

    if (!(fptr = fopen(fname, "r"))) //check if file exists
    {
        puts("File not found");
        exit(EXIT_FAILURE);
    }

    while (i < HEIGHT && fgets(line[i], LENGTH, fptr)) //to avoid container overflow limit the number of lines to HEIGHT
    {
        line[i][strcspn(line[i], "\n")] = '\0'; // replace newline character possibly consumend by fgets with null-terminator
        printf("%s\n", line[i]);                //test print
        i++;
    }
    fclose(fptr); //close file
}
0 голосов
/ 04 апреля 2020

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

И, во-вторых, тип char** , тип возвращаемого значения показанной функции и тип char ( * )[LENGTH], тип возвращаемого выражения, различаются.

Вы можете динамически размещать в функции массив массивов и возвращать его.

Например,

char (* OpenFile() )[LENGTH] {

    char ( * line )[LENGTH] = malloc( HEIGHT * sizeof( char[LENGTH] ) );
    //...

    retirn line;
}

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

Или вы можете определить массив с помощью спецификатора хранилища stati c like

char (* OpenFile() )[LENGTH] {

    static char line[JEIGHT][LENGTH];
    //...

    retirn line;
}

Обратите внимание, что это утверждение

line[i][strlen(line[i]) - 1] = '\0';

небезопасно. Не обязательно, чтобы функция fgets добавляла введенную строку с символом новой строки '\n'. Безопасный подход заключается в следующем

line[i][ strcspn( line[i], "\n" ) ] = '\0';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...