Я хочу взять 4 строки в качестве входных данных и отобразить в другом массиве - PullRequest
1 голос
/ 26 апреля 2020

Я хочу взять 5 строк в качестве входных данных и отобразить их в другом массиве, используя двумерные массивы и обозначения указателя. Однако я застрял.

Я путаю нотацию массива и указателя в вызове и определении функции и то, как указатель массива 2d используется, когда для доступа к указанному действию c. Каждая строка имеет максимальную длину 20, и я хочу 5 таких строк.

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

void *func(char (*str1)[20]);
void *func1(char (*str1)[20]);

int
main(void)
{
    char (*a)[20];

    func1(a);
    printf("The string you just entered is:\n");
    func(a);
}

void *
func(char (*str1)[20])
{
    int i = 0;
    int j = 0;

    char (*str2)[20];

    while (j < 5) {
        while (*str1[i] != '\0') {
            *str2[i] = *str1[i];
            i++;
        }
        puts(str2[j]);
        j++;
    }
}

void *
func1(char (*str1)[20])
{
    int i = 0;
    int j = 0;
    char *res;

    while (j < 5) {
        res = fgets(str1[j], 20, stdin);

        if (res) {
            while (*str1[i] != '\n' && *str1[i] != '\0')
            {
                i++;
            }

            if (*str1[i] == '\n') {
                *str1[i] = '\0';
            }
            else {
                while (getchar() != '\n') {
                    continue;
                }
            }
        }

        j++;
    }
}

1 Ответ

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

Есть некоторые проблемы с вашим кодом.

Это требует void* return:

void *func(char (*str1)[20]);  
void *func1(char (*str1)[20]);

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

char (*a)[20]; 

Если вы хотите сохранить (*a)[20] обозначение, которое вам все еще нужно инициализировать, выделяя достаточно памяти для хранения назначаемых вами строк.

Таким образом, его 5 строк по 20 символов в каждой, то есть 20 * 5 символов, это будет выглядеть примерно так с комментариями:

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

#define N 5      //macros to hold the dimensions
#define LENGTH 20

void* func(char (*str1)[LENGTH]); //you can return str2
void func1(char (*str1)[LENGTH]); //no return needed here

int main(void)
{
    char (*a)[LENGTH];
    char (*b)[LENGTH];  //to hold str2, otherwise it's lost at function return

    if(!(a = malloc(N * LENGTH))) { // allocationg necessary memory, char has the size of 1 byte
       perror("No memory!");
    }

    func1(a);   
    b = func(a); //assigning str2 to b

    puts("The strings you just entered are:"); //printing str2's now assingned to b
    for(int i = 0; i < N; i++){
        puts(b[i]);
    }
}

void* func(char (*str1)[LENGTH])
{
    char(*str2)[LENGTH];
    str2 = malloc(N * LENGTH); //also needs memory allocation

    for (int i = 0, j; i < N; i++) //declaring i and j inside the scope of for
    {
        for (j = 0; j < LENGTH && str1[i][j] != '\0'; j++)
        {
            str2[i][j] = str1[i][j]; //copying char by char, note thar you can use strcpy or similar to copy the str1 to str2
        }
        str2[i][j] = '\0'; //null terminate str2
    }
    return str2; //returning str2
}

void func1(char (*str1)[LENGTH])
{
    int i = 0;
    while(i < N && printf("Enter string %d: ", i + 1) && fgets(str1[i], LENGTH, stdin)) //getting all the strings
    {
        str1[i][strcspn(str1[i], "\n")] = '\0'; // replace \n
        i++;
    }
}

Обратите внимание, что некоторые из logi c в ваших функциях неисправны и будут вызывать неопределенное поведение, я изменил его, сохранив char by char copy, хотя вы можете использовать библиотечные функции, такие как strcpy, для копирования строк.

Лично я бы использовал двойную запись указателя, он все же позволяет вам получить доступ к строкам, как если бы они находились в классе. c 2D массив, т.е. с использованием str[i][j] нотация.

Вот возможная реализация с использованием только указателей с некоторыми комментариями для пояснения:

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

#define N 5
#define LENGTH 20

void func(char **str1);
void func1(char **str1, char **str2);

int main() {

    char **a, **b; //double pointers emulate 2D array

    if (!((a = malloc(N * sizeof(*a))) && (b = malloc(N * sizeof(*b))))) { //allocate memory for lines
        perror("Memory allocation failed!");
        return 1;
    }

    for (int i = 0; i < N; i++) { //allocate memory for columns
        if (!((a[i] = malloc(LENGTH)) && (b[i] = malloc(LENGTH)))) {
            perror("Memory allocation failed!");
            return 1;
        }
    }
    func1(a, b);
    printf("The strings you just entered are:\n");
    func(b);
}

void func(char **str2) { 

    for (int i = 0; i < N; i++) { //print all the arrays
        puts(str2[i]);
    }
}

void func1(char **str1, char **str2) {

    for (int i = 0; i < N; i++) {
        printf("Enter string %d: ", i + 1);
        if (fgets(str1[i], LENGTH, stdin)) { //get strings
            str1[i][strcspn(str1[i], "\n")] = '\0'; //remove \n from string
            strcpy(str2[i], str1[i]); //copy strings to second array
        }
    }
}

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

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