Але все ж таки пробую використати calloc() за призначенням, і ніби то вийшло, але є свої проблеми:
1. Чи можна якось покращити частину input() ?
2. В функції output() є такі моменти коли curr_gr + curr_col дають результат більший ніж nlines. Тобто коли ми заповнюємо інші колонки пробілами, то ми перше перевіряємо рядок із цієї групи, чи він зараз на позиції нуль-символу (тобто чи він повністю виведений) і якщо так - виводимо пробіли. Але трапляються ситуації, коли в ряд із 4-ьох колонок залишилось вивести тільки один рядок. Наприклад у нас 9 рядків всього. Виходить в решту три треба вивести пробіли. Але зазвичай ми перевіряємо чи решта три рядки стоять на нуль символах, але тут у нас решти взагалі немає. В принципі цю проблему можна вирішити.
Я думав додати в input() код, який би доповнював би в пам’ять іще рядки, в яких тільки нуль-символи, щоб число було пропорційно колонкам. Або зробити теж саме в output.
В цілому проблема виникає тут:
while( curr_ch < col_width // Іще є куди записувати
// і поточний рядок іще не закінчився (є іще символи)
&& ptr[ curr_gr+curr_col ][ last_ch+curr_ch ] != '\0')
Коли curr_gr + curr_col, дають число більше ніж nlines. Треба б просто цей шматок коду просто пропустити і перейти до виведення пробілів. Але не можу придумати рішення, щоб воно підійшло нормально, порадьте щось.
Ось код
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STRING_NUMBER 100
#define MAX_STRING_LENGTH 128
#define MAX_COLUMNS 5
#define OUTPUT_AREA 60
/*
*
*/
int input(char **ptr);
void output(char **ptr, int nlines, int columns);
int main(int argc, char** argv) {
int i, j, cols, nlines;
char *lineptr[MAX_STRING_NUMBER];
/* визначення кількості колонок */
do{
printf("Input number of columns (0 - default): ");
scanf("%d", &cols);
} while (cols < 0 || cols > MAX_COLUMNS);
if (cols == 0){
cols = 1;
}
/* читання рядків із файлу */
nlines = input(lineptr);
/* вивід рядків в колонки */
output(lineptr, nlines, cols);
return (EXIT_SUCCESS);
}
int input(char **lineptr){
int c, // Приймає символ
i; // Лічильник
int curr_ln = 0, // Поточний рядок
curr_ch = 0; // Поточний символ
char buffer[MAX_STRING_LENGTH]; // Буфер для поточного рядка
FILE *fp; // Покажчик для лексем файлу
fp = fopen("user_strings.txt", "r"); // Відкриваємо файл на читання
if(!fp) // Файлу немає
return (-1);
while( ((c = fgetc(fp)) != EOF) // Йдемо до кінця файлу
&& curr_ln < MAX_STRING_NUMBER // Запобігання виходу за межі масиву
&& curr_ch < MAX_STRING_LENGTH ){
if(c != '\r' && c != '\n' && c > 0){ // Рядок не закінчився
buffer[ curr_ch ] = (char) c; // Запис символу в масив
curr_ch++; // Приготуємо лічильник для наступного символу
} else if(c == '\n'){ // Рядок закінчився
buffer[ curr_ch ] = '\0'; // Додаємо нуль-символ в кінець рядка
lineptr[ curr_ln ] = calloc(curr_ch+1, sizeof(char)); // Виділяємо пам’ять для поточного рядка
for(i = 0; i <= curr_ch; i++){
lineptr[ curr_ln ][ i ] = buffer [ i ]; // Копіюємо поточний рядок із буфера
// в виділену пам’ять
}
curr_ln++; // Приготуємо лічильник для наступного рядка
curr_ch = 0; // Обнулимо лічильник символів
}
}
if(c == EOF && curr_ch != 0){ // Якщо після останнього рядку не був
// поставлений символ нового рядка
buffer[ curr_ch ] = '\0';
lineptr[ curr_ln ] = calloc(curr_ch, sizeof(char));
for(i = 0; i <= curr_ch; i++){
lineptr[ curr_ln ][ i ] = buffer [ i ]; // Копіюємо поточний рядок із буфера
// в виділену пам’ять
}
}
fclose(fp); // Закриваємо файл
return curr_ln;
}
void output(char **ptr, int nlines, int cols){
char c;
int toprint, posv[MAX_COLUMNS];
int curr_col = 0, // Поточна колонка
curr_ch = 0, // Поточний символ
last_ch = 0, // Останній символ, який виводився із поточного рядка
curr_gr = 0, // Перший рядок поточної групи рядків
col_width = ( OUTPUT_AREA - cols - 1 ) / cols; // визначення ширини колонок
/* друк шапки */
for(curr_col = 0; curr_col < cols; curr_col++){
putchar('|');
for(curr_ch = 0; curr_ch < col_width; curr_ch++){
putchar('=');
}
}
putchar('|');
putchar('\n');
/* друк колонок */
for(curr_gr = 0; curr_gr <= nlines; curr_gr += cols){
for(curr_col = 0; curr_col < cols; curr_col++){
// Сюди записуються позиції,
// на яких вивід поточного рядка був призупинений
posv[curr_col] = 0;
}
toprint = 1; // Обов’язково на друк є хоча б один рядок
while(toprint > 0){
putchar('|');
toprint = 0; // Поки що невідомо скільки рядків треба друкувати
for(curr_col = 0; curr_col < cols; curr_col++){
curr_ch = 0; // Перший символ поточного рядка
last_ch = posv[curr_col]; // Останній символ поточного рядка
while( curr_ch < col_width // Іще є куди записувати
// і поточний рядок іще не закінчився (є іще символи)
&& ptr[ curr_gr+curr_col ][ last_ch+curr_ch ] != '\0'){
// просто друкувати по порядку
c = ptr[ curr_gr+curr_col ][ last_ch+curr_ch ];
putchar( ptr[ curr_gr+curr_col ][ last_ch+curr_ch ] );
curr_ch++; // наступний символ
}
// Якщо цикл закінчився, але рядок іще не повністю виведений
if(ptr[ curr_gr+curr_col ][ last_ch+curr_ch ] != '\0'){
toprint++; // Треба закінчити друк іще одного рядка
posv[curr_col] += curr_ch; // Запам’ятовуємо місце, де ми зупинились
} else { // В іншому разі треба запам’ятати місце нуль символу
// виведеного рядка, якщо якийсь із рядків групи не
// повністю виведений
posv[curr_col] = last_ch + curr_ch;
}
// Якщо ми закінчили виводити рядок, а місце іще залишилось -
// заповнюємо його пробілами
while(curr_ch < col_width){
putchar(' ');
curr_ch++;
}
putchar('|');
}
putchar('\n');
}
}
}