如何将用户输入中的字符行存储到 C/C++ 中动态分配的锯齿状二维字符数组?

问题描述

假设 char 的每一行都以 'E' 字符结束,最后一行以 'T' 字符结束。我正在努力打印出用户给出的字符行,不包括终止的字符。

    必须使用 malloc()、calloc()、realloc() 和 free() 函数之一。

示例输入和输出可能是这样的:

输入 输出
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;
        }
}

解决方法

这是您可以执行的一种 C++ 方式,

  string line;

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

这里是 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;
}
,

您的代码是 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++ not C. 的一部分,我们需要以 C 风格编写它。由于这是您的功课,我不会发布整个解决方案,但是,我会提出一些意见以帮助您完成。

逻辑

代码中的第一个问题是

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

这将覆盖读取最后一个字符的行,在您的情况下,每行都是 E。这将变成:

    chars[colsize] = c;
    colsize++;

Malloc

我们必须将您的字符存储在我们动态分配的矩阵中(我们不能使用向量)。您的矩阵 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 个释放。所以,没有内存泄漏。释放矩阵的方式与分配矩阵的方式相反。为什么?我们需要按照我们分配它们的方式为每一行释放其底层指针。

for (i = 0; i < r; i++)
        free(chararr[i]);
         
free(chararr);