Проблема с выводом символов на экран

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

Когда посимвольно считываю строку из файла, то выскакивает символ "?" в прямоугольнике.

Замена кодировки к Windows-1251 или UTF-8 ни к чему не привела.

// Для решения задачи вам нужно ввести строки с помощью функций gets или fgets, разбить строку 
// на слова и выбрать нужные (функция scanf с форматом %s вводит строку до пробела, но в 
// данной задаче вам не нужно так делать!). Стандартные функции работы со строками НЕ 
// использовать! Обратите внимание, что во всех случаях слова могут разделяться любым(!) 
// количеством символов, не относящихся к слову(будем считать, что к слову относятся большие и 
// маленькие латинские буквы и цифры). Желательно всю обработку выполнить за один проход 
// строки, хотя это возможно не во всех вариантах. Обязательно проверить работу программы на 
// пустой строке и на строке, состоящей только из символов, не относящихся к слову. 
// Сформировать строку, добавляя к каждой заданной подстроке другую заданную подстроку.

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <windows.h>

#define _CRT_SECURE_NO_WARNINGS

int DefineSize(FILE* file);
void ReadStr(FILE* file, char* str);
char* FormNewStr(char* str_one, int n_one, char* str_two, int n_two, char* str_three, int 
n_three);
int FindSubstr(char* str, int n, char* substr, int ns);
char* Concat(char* str, int n, char* substr, int ns, int index);
void Show(char* str);

int main(int argc, char* argv[])
{
    FILE* file_one, * file_two, * file_three;
    char* str_one, * str_two, *str_three, *new_str;
    int n_one, n_two, n_three;

    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

    setlocale(LC_ALL, "rus");

    if (argc < 3)
    {
        printf("Недостаточное число параметров.\n");
        return 0;
    }

    fopen_s(&file_one, argv[1], "r");
    fopen_s(&file_two, argv[2], "r");
    fopen_s(&file_three, argv[3], "r");
    if (file_one == nullptr || file_two == nullptr || file_three == nullptr)
    {
        printf("Не все файлы находятся в директории проекта.\n");
        return 0;
    }
    else
    {
        if (feof(file_one) || feof(file_two) || feof(file_three)) 
        { 
            fclose(file_one); 
            fclose(file_two); 
            fclose(file_three); 
                            
            printf("Какие-то текстовые файлы пустые.\n"); 
            
            return 0; 
        }
        else
        {
            fseek(file_one, 0, SEEK_CUR);
            fseek(file_two, 0, SEEK_CUR);
            fseek(file_three, 0, SEEK_CUR);

            n_one = DefineSize(file_one);
            str_one = (char*)malloc(sizeof(char) * n_one);

            n_two = DefineSize(file_two);
            str_two = (char*)malloc(sizeof(char) * n_two);

            n_three = DefineSize(file_three);
            str_three = (char*)malloc(sizeof(char) * n_three);

            fseek(file_one, 0, SEEK_CUR);
            fseek(file_two, 0, SEEK_CUR);
            fseek(file_three, 0, SEEK_CUR);

            ReadStr(file_one, str_one);
            ReadStr(file_two, str_two);
            ReadStr(file_three, str_three);

            fclose(file_one);
            fclose(file_two);
            fclose(file_three);

            Show(str_one);
            Show(str_two);
            Show(str_three);

            new_str = FormNewStr(str_one, n_one, str_two, n_two, str_three, n_three);

            Show(new_str);

            free(str_one);
            free(str_two);
            free(str_three);
            free(new_str);

            return 0;
        }
    }
}

int DefineSize(FILE* file)
{
    int n = 0;
    char ch;

    while (ch = fgetc(file) != EOF)
    {
        n++;
        printf("%c ", ch);
    }
    printf("\n");

    return n;
}

void ReadStr(FILE* file, char* str)
{
    int counter = 0;
    char ch;

    while (ch = fgetc(file) != EOF)
    {
        str[counter] = ch;
        counter++;
    }
}

char* FormNewStr(char* str_one, int n_one, char* str_two, int n_two, char* str_three, int n_three)
{
    if (str_one != nullptr && str_two != nullptr && str_three != nullptr)
    {
        int index = FindSubstr(str_one, n_one, str_two, n_two);
        char* new_str = str_one;

        while (index != -1)
        {
            char* auxilary_str = (char*)malloc(sizeof(char) * (n_one - index - n_two));

            if (auxilary_str != nullptr)
            {
                for (int i = index + n_two; i < n_one; i++)
                {
                    auxilary_str[i - index - n_two] = str_one[i];
                }

                new_str = Concat(str_one, n_one, str_three, n_three, index);
                index = FindSubstr(auxilary_str, n_one - index - n_two, str_two, n_two);
            }
        }

        return new_str;
    }
    else
    {
        return nullptr;
    }
}

int FindSubstr(char* str, int n, char* substr, int ns)
{
    if (ns > n)
    {
        return -1;
    }
    else
    {
        bool flag = true;

        for (int i = 0; i < n - ns + 1; i++)
        {
            for (int j = 0; j < ns; j++)
            {
                if (str[j + i] != substr[j])
                {
                    flag = false;
                }
            }

            if (flag)
            {
                return i;
            }
        }

        return -1;
    }
}

char* Concat(char* str, int n, char* substr, int ns, int index)
{
    char* new_str = (char*)malloc(sizeof(char) * (n + ns));

    if (new_str != nullptr)
    {
        for (int i = 0; i < index; i++)
        {
            new_str[i] = str[i];
        }

        for (int i = index; i < index + ns; i++)
        {
            new_str[i] = substr[i - index];
        }

        for (int i = index + ns; i < n; i++)
        {
            new_str[i] = str[i];
        }

        return new_str;
    }
    else
    {
        return nullptr;
    }
}

void Show(char* str)
{
    if (str == nullptr)
    {
        printf("Строка пуста.\n");
    }
    else
    {
        int counter = 0;

        while (str[counter] != '\0')
        {
            printf("%c ", str[counter]);
            counter++;
        }
        printf("\n");
    }
}

//file_one.txt
qwcd

//file_two.txt
cd

//file_three.txt
345

Результат отладки на 81-ой строчке(см. фото).

Объясните мне, тупице, где я что не так делаю?

Кодировки менял и в блокноте, и здесь. Бесполезно.

Что не так-то?

Меня даже не так волнует, правильно ли я сделал задание, но вот стопор на этом..введите сюда описание изображения


Ответы (1 шт):

Автор решения: Harry

Я бы настойчиво рекомендовал исправить самую главную ошибку:

Выражения

while (ch = fgetc(file) != EOF)

заменить на

while ((ch = fgetc(file)) != EOF)

(вспомните о приоритете операций сравнения и присваивания).

Ну, и остальные...

Например, в DefineSize возвращать не n, а n+1

В ReadStr последней строкой добавить str[counter] = 0;.

Все SEEK_CUR заменить на SEEK_SET.

Дальше — как вы там форматируете новую строку — не смотрел, да вы об этом и не спрашивали.

→ Ссылка