Как сохранить строки символов из пользовательского ввода в динамически выделяемый массив зубчатых 2d символов в C/С++?

Учитывая, что каждая строка char заканчивается символом «E», а последняя строка заканчивается символом «T». Я изо всех сил пытаюсь распечатать строки символов, заданные пользователем, за исключением завершающих символов.

    Обязательно использовать одну из функций malloc(), calloc(), realloc() и free().

Пример ввода и вывода может быть таким:

Input Output
A B C E
V F E
K T
A B C
V F
K

Моя попытка:

#include <iostream>
#include <sstream>
#include <string>
#include <math.h> 
#include <vector>
#include <stdio.h> 

using namespace std;


int main()
{

   char c;
   int rowsize = 0 ,colsize = 0;
   char** chararr; 
   chararr = (char**)malloc(sizeof(char*));



   vector<int> colsizes;

   char chars[20];

   do {

       cin >> c;
       
       
        colsize++;

        for(int i=0; i<colsize;i++) {
            chars[i] = c;
        }
 


       if ( c ==  'E') { 
           

           ++rowsize;
           colsizes.push_back(colsize);


            chararr = (char**)realloc(chararr,rowsize*sizeof(char*));

            for (int i = 0; i < rowsize; ++i){
            *(chararr + i) = (char*)malloc(colsizes[i] * sizeof(char));
    
            for (int j = 0; j < colsizes[i]; ++j) {

              chararr[i][j] = chars[j];
            
             }
        }


           colsize = 0 ;

           continue;       
       }

   }while(c != 'T');

    colsizes.push_back(colsize);


 for (int i = 0; i < rowsize; ++i){
    
        for (int j = 0; j < colsizes[i]; ++j) {

             std::cout << chararr[i][j] << " ";
            
             }

             std::cout << endl;
        }
}


person Powerful blaster    schedule 04.03.2021    source источник
comment
Вы должны выбрать один язык. Обычные решения C будут изначально использовать семейство alloc, вместо них обычные решения C++ должны использовать векторы. IHMO, если вам нужно использовать alloc, вам лучше использовать C... Но текущий код - C++ и не использует malloc...   -  person Serge Ballesta    schedule 04.03.2021
comment
Странно, что вы обязаны использовать функции семейства malloc, поскольку в C++ есть более подходящие функции new/delete и new[]/delete[], которые безопаснее использовать (поскольку они не просто выделяют память)   -  person Fareanor    schedule 04.03.2021
comment
Вы изучаете C или C++ в этом классе? Это разные языки.   -  person rustyx    schedule 04.03.2021


Ответы (3)


Вот один из способов С++, который вы можете сделать,

  string line;

  while (getline(cin, line)) {
    stringstream str(line);
    string word;
    while (str >> word) {
      if (word == "E") {
        break;
      }
      cout << word << " ";
    }
    cout << endl;
  }
person starboy_jb    schedule 04.03.2021

вот еще способ на CPP, таким образом нужно вводить букву за буквой и в конце ее печатать, если получится сразу вся строка поменять цикл while на std::getline()

#include <iostream>
#include <vector>

int main()
{
    char c;
    std::vector<char> vec;
    while(c != 'T')
    {
        std::cin >> c;
        vec.push_back(c);
        
    }
    
    for(auto& c : vec)
    {
        if(c == 'E')
        {
            std::cout << "\n";
        } else 
        {
            std::cout << c << " ";
        }
    }

    return 0;
}
person yaodav    schedule 04.03.2021

Ваш код представляет собой смесь C++ и C. Поэтому я собираюсь пойти дальше и предположить, что это C++. Я буду писать предложения на C++, за которыми следуют замечания по реализации в стиле C.

vector<vector<char>> v; 
do {
v.push_back(vector<char>{}); 
do {
   cin >> c; 
   v.push_back(c);
} while(c != 'E' && c != 'T');
} while(c != 'T');

for(std::size_t i = 0; i<v.size(); i++) { for(std::size_t j = 0; j<v[i].size() - 1; j++) {std::cout << v[i][k] << " "} }

Это уродливое решение C++, которое, как ожидается, будет работать. j<v[i].size() - 1 для пропуска завершающих символов.

Теперь malloc и free являются обязательными, что означает, что эта домашняя работа должна быть написана в стиле C. Не используйте векторы, векторы являются частью C++, а не C. напишите это в стиле C. Поскольку это ваша домашняя работа, я не буду публиковать все решение, однако сделаю несколько замечаний, чтобы помочь вам в этом.

Логика

Первая проблема в вашем коде

    colsize++;
    for(int i=0; i<colsize;i++) {
        chars[i] = c;
    }

Это переопределит строку с последним прочитанным символом, E в вашем случае для каждой строки. Это станет:

    chars[colsize] = c;
    colsize++;

Маллок

Мы должны хранить ваши символы в матрице, которую мы динамически выделяем (мы не можем использовать векторы). Ваш матричный chararray не распределен должным образом. Это приведет к большому количеству головной боли. Ниже неправильно

int rowsize = 0, colsize = 0;
char **chararr;
chararr = (char **)malloc(sizeof(char *));

Вот как вы это делаете:

scanf("%d %d", &r, &c); 
char** chararr = malloc(sizeof(char*) * r); 
for (i = 0; i < r; i++) 
chararr[i] = malloc(c);

Свободно

Теперь ваша матрица символов выделена. Поскольку он был выделен динамически, нам нужно освободить его вручную. Всегда помните, если в вашем коде есть n malloc, вы ожидаете, что у вас будет n frees. Так что утечки памяти нет. Освобождение матрицы будет происходить в обратном порядке. Почему? Нам нужно освободить базовые указатели для каждой строки так, как мы их выделили.

   

for (i = 0; i < r; i++)
        free(chararr[i]);
         
free(chararr);
person Oussama Ben Ghorbel    schedule 04.03.2021
comment
что такое r и c в вашем коде? Я предполагаю, что это означает размер строки и столбца. Я не хочу сканировать эти номера от пользователя. Программа должна только сканировать символы и вручную вычислять размер столбца для каждой строки. - person Powerful blaster; 04.03.2021
comment
Тогда вам придется перераспределять ресурсы по мере роста, что делает проблему другой. - person Oussama Ben Ghorbel; 04.03.2021