Проблема с выводом в счетчике количества повторений символов
Программа считает сколько раз повторялся тот или иной символ в текстовом документе. Код компилируемый, но не выводит подсчитанное ни в csv ни в консоль. Дебагинг ругается на цикл который записывает из массивов в csv.
#include <iostream>
#include <fstream>
using namespace std;
int main(void) {
int size = 1;
char* symbolElem = new char[size];
char currentSymbol, symbolForComparing;
int* howManySymbMeet = new int[size];
bool isLoopComplete = false;
ifstream textFile;
textFile.open("file.txt");
while (textFile.get(currentSymbol)) {
symbolForComparing = '\0';
for (int i = 0; i < 256; i++) {
if (currentSymbol == symbolForComparing) {
for (int j = 0; j < size; j++) {
if (symbolElem[j] == symbolForComparing) {
(howManySymbMeet[j])++;
isLoopComplete = true;
break;
}
}
if (!isLoopComplete) {
symbolElem[size] = symbolForComparing;
howManySymbMeet[size] = 0;
(howManySymbMeet[size])++;
size++;
}
}
symbolForComparing++;
isLoopComplete = false;
}
}
textFile.close();
ofstream csvFile;
csvFile.open("output.csv");
for (int i = 0; i < size; i++) {
csvFile << symbolElem[i] << ", " << howManySymbMeet[i] << endl;
}
csvFile.close();
delete [] symbolElem;
delete [] howManySymbMeet;
return 0;
}
Ответы (2 шт):
Вы используйте C++, Давайте попробуем использовать современный С++
На данный день, уже лет 15 не принято использовать оператор new в явном виде(допускается использовать его как размещающий). Пользуйтесь контейнерами и умными указателями
Алгоритм :
1) Проверяете что Ваш файл есть, и открываете его.
2) Заводите std::map для подсчета вхождений символов и заполняете его.
3) Создаете csv файл и дампите туду содержимое map
4) ПРОФИТ
Вот пример кода:
#include <iostream>
#include <fstream>
#include <filesystem>
#include <map>
#include <algorithm>
#include <iterator>
std::map<unsigned char, std::size_t> CalcSymbls(std::filesystem::path f_path) {
if (!std::filesystem::exists(f_path)) {
throw std::runtime_error{"File not found!"};
}
std::ifstream in_stream(f_path, std::ios::out);
if (!in_stream.is_open()) {
throw std::runtime_error{"Error open file!"};
}
in_stream.unsetf(std::ios_base::skipws);
std::map<unsigned char, std::size_t> symbls;
auto f_obj{[&](unsigned char ch){ symbls[ch]++;}};
std::for_each(std::istream_iterator<char>(in_stream), std::istream_iterator<char>(), f_obj);
return symbls;
}
void WriteCSV(std::filesystem::path out_file_path, std::map<unsigned char, std::size_t> data) {
std::ofstream out_csv_stream(out_file_path, std::ios::out);
if (!out_csv_stream.is_open()) {
throw std::runtime_error{"Error open file"};
}
auto f_obj{[&](std::pair<unsigned char, std::size_t> val){ out_csv_stream << val.first << ";" << val.second << "\n";}};
std::for_each(std::begin(data), std::end(data), f_obj);
}
int main() {
std::string file_name{"data"};
auto file_path{std::filesystem::current_path() / file_name};
std::map<unsigned char, std::size_t> symbls;
try {
symbls = CalcSymbls(file_path);
} catch (std::exception& exc) {
std::cerr << exc.what() << std::endl;
return -1;
} catch (...) {
std::cout << "unknown error ~ !"<< std::endl;
return -10;
}
std::string out_name{"out.csv"};
auto out_file_path{std::filesystem::current_path() / out_name};
try {
WriteCSV(out_file_path, symbls);
} catch (std::exception& exc) {
std::cerr << exc.what() << std::endl;
return -2;
} catch (...) {
std::cout << "unknown error ~ !"<< std::endl;
return -10;
}
return 0;
}
Вы выделяете массивы из 1 (прописью: одного) элемента:
int size = 1;
char* symbolElem = new char[size];
после чего начинаете писать в элементы с индексом явно больше 0... Получаете UB - неопределенное поведение, при котором может не работать что угодно.
Откровенно, я не понимаю, зачем для решения такой простой задачи такой сложный код, да и массива в 256 элементов достаточно, его можно не выделять динамически - просто нет смысла...
Вот вся программа:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char c;
int count[256] = {};
ifstream text("file.txt");
while (text.get(c)) count[(unsigned char)c]++;
ofstream csv("output.csv");
for (int i = 0; i < 256; i++)
if (count[i] && i != '\n') csv << char(i) << ", " << count[i] << "\n";
}