IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

 
 Ответить  Открыть новую тему 
> Буфер вывода или кривой код., c++/minGW
сообщение
Сообщение #1


Бывалый
***

Группа: Пользователи
Сообщений: 222
Пол: Мужской
Реальное имя: Andrew

Репутация: -  0  +


 
#include <algorithm>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <windows.h>
using namespace std;
//использование стандартного пространства имен


bool ForCompanation(string word1, string word2)//функция-предикат для сортировки
{
return word1.size() > word2.size();//возврашает true , если длина 1го слова < 2го слова
}

bool ThreadFunction(char *);//прототип функции

CRITICAL_SECTION Crit;
char bufc;//символ для формирования имени рез. файла
string rezfilename = "Результат";
clock_t StartTime, EndTime;//переменные для фиксации время работы программы

int main(int argc, char *argv[])
{
InitializeCriticalSection(&Crit);
DWORD ID[10];//массив DWORD для записи ID потоков
HANDLE ThreadHandle[10];//массив дескрипторов для потоков
rezfilename += itoa(argc - 1, &bufc, 10);//преобразуем кол-во аргументов-1 в символ
rezfilename += ".txt";//добовляем расширение файла
StartTime = clock();
if (argc < 2 || argc > 11)//если кол-во аргументов <2 или >11
{
cout << "Ne verno vvedeni parametry zapuska!";
exit(0);//выход из программы
}
//читаем файлы
for (int i = 1; i <= argc - 1; i++)//цикл от 1 до кол-ва указанных файлов
{
ThreadHandle[i] = CreateThread(NULL,0, LPTHREAD_START_ROUTINE(
ThreadFunction), argv[i], CREATE_SUSPENDED,&ID[i]);//запуск функции на обработки файла,argv[i] - имя файла
if (ThreadHandle == NULL)//если поток не создан то выход из приложения
{
cout << "Error thread!";
exit(0);
}
else
ResumeThread(ThreadHandle[i]);//иначе "будим" поток
}
WaitForMultipleObjects(argc, ThreadHandle, TRUE,INFINITE);//функция
EndTime = clock();//записываем текущее время что бы посчитать время обработки
cout << "\nVremya obrabotki : " << EndTime - StartTime << " ms";
DeleteCriticalSection(&Crit);
return 0;
}

bool ThreadFunction(char *fname)
{
string filestring;//строка для хранения считанного файла
string buffer;//строка для хранения временных переменных
ofstream rezfile;//файл результатов
ifstream file;//логич. файл для чтения
char d = ' ';//символ пробел - разделитель слов
unsigned int dcount = 0;//кол-во пробелов в предложении
unsigned int DPos = 0;//переменная хранит положение пробела в строке
vector<string> ArrayOfWords;//массив-вектор из слов
file.open(fname, ios::binary);//открываем файл
file.seekg(0, std::ios_base::end);//помешаем указатель внутри файла в конец файла
filestring.resize(file.tellg());//изменяем размер строки по длине файла
file.seekg(0, std::ios_base::beg);//помешает указатель внутри файла в начало файла
char ch[filestring.size()];//создаем чар-массив размером xstr
file.read(ch, filestring.size());//читаем данные размером строки xstr в чар массив из файла
file.close();//закрываем файла
filestring = ch;//присваиваем строке xstr значение массива mychar
dcount = 0;//обнуляем позицию разделителя слов
for (size_t i = 0; i < filestring.size(); i++)
//size_t = максимальный размер типа int в системе = размеру unsigned int
//цикл до конца строки(кол-во итераций = размеру строки s)
if (filestring.at(i) == d)//если символ на i-ой позиции строки s= разделителю devider
dcount++;//то увеличить кол-во разделителей на 1
buffer.clear();//очищаем строку
DPos = 0;//обнуляем позицию разделителя
for (size_t i = 0; i < dcount + 1; i++)//цикл чтения слов из целой строки
{
DPos = filestring.find(d);//запоминаем позицию пробела
buffer.append(filestring, 0, DPos);//записывает слово в спомогательную строку
filestring.erase(0, DPos + 1);//удаляем записанное слово
ArrayOfWords.push_back(buffer);//записываем слово в массив-вектор
buffer.clear();//очищаем строку
}



//==============вот с этого места вообще перестает выводить что-либо в потоки вывода.


filestring.clear();//очишаем строку содержавшую содержание файла
sort(ArrayOfWords.begin(), ArrayOfWords.end(), ForCompanation);//сортировка по длине слова
sort(ArrayOfWords.begin(), ArrayOfWords.end());//сортировка по алфавитному порядку
ArrayOfWords.erase(ArrayOfWords.begin() + 100, ArrayOfWords.end());//удаляем не нужные слова(от 100 слова и до конца массива)
EnterCriticalSection(&Crit);//входим в крит. секцию
rezfile.open(rezfilename.data(), ios::app);//открываем рез. файл на дозапись
rezfile << "\nВот 100 самых длинных слов в алфавитном порядке для файла "//запись в рез. файл заголовка
<< fname << " : " << endl;//и имени обрабатываемого файла
EndTime = clock();
for (size_t i = 0; i < ArrayOfWords.size(); i++)
//
//цикл записи слов в рез. файл от 0 до размера массива ArrayOfWords
rezfile << ArrayOfWords[i] << endl;//запись i-го слова в рез. файл
rezfile.close();
LeaveCriticalSection(&Crit);//выход из крит. секции
return 0;
}



Сдается мне, где-то я с потоками ввода/вывода напортачил, переполняются они что-ли?В чем может быть проблема?На кол-во комментариев не обращайте внимания, пишу для друга почти не знакомого с c/c++..
Забыл добавить, что для теста необходимо запускать через cmd, указывая при запуске пути к текстовому файлу, содержащему текст без знаков препинания, в общем слова разделенные между собой пробелами.

Сообщение отредактировано: Andrewshkovskii -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Бывалый
***

Группа: Пользователи
Сообщений: 222
Пол: Мужской
Реальное имя: Andrew

Репутация: -  0  +


В общем он файл-то даже и не создает...непонимат.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Гость






Цитата
Не создает файл и не выводит ничего из потока.
Неправда... Параметры - t1.txt, t2.txt, t3.txt, каждый содержит произвольный английский текст. Имя файла создается так:

       char s[3] = {0};
sprintf(s, "%d", argc - 1);
rezfilename += s[0];
rezfilename += ".txt";
, в Code::Blocks itoa не присутствует...

Запускаю программу. Файл "Результат3.txt" создан, только содержит не 100 самых длинных слов, поскольку надо немного по-другому сортировать, чтобы было именно 100 самых длинных:

	sort(ArrayOfWords.begin(), ArrayOfWords.end(), ForCompanation); // сортировка по длине слова
ArrayOfWords.erase(ArrayOfWords.begin() + 100, ArrayOfWords.end());
sort(ArrayOfWords.begin(), ArrayOfWords.end()); // сортировка по алфавитному порядку

Ну, и что-то намудрено у тебя с крит. секциями, обрабатывается только первый файл, остальные потоки не получают доступа в КС, и не обрабатываются... Но с потоками нет никакой проблемы, все нормально... Проверяй код.

Чуть позже посмотрю более внимательно...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Бывалый
***

Группа: Пользователи
Сообщений: 222
Пол: Мужской
Реальное имя: Andrew

Репутация: -  0  +


Да насчет сортировки это я вчера увидел, но забыл тут исправить. Не знаю, у меня вообще файл не создается и из потока либо не выводит, либо выводит будто после завершения родительского потока..чушь какая-то
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Бывалый
***

Группа: Пользователи
Сообщений: 222
Пол: Мужской
Реальное имя: Andrew

Репутация: -  0  +


Программа, видимо, не ждет потоки, ибо :

for (int i = 1; i <= argc - 1; i++)//цикл от 1 до кол-ва указанных файлов
{
ThreadHandle[i] = CreateThread(NULL,0, LPTHREAD_START_ROUTINE(
ThreadFunction), argv[i], CREATE_SUSPENDED,&ID[i]);//запуск функции на обработки файла,argv[i] - имя файла
if (ThreadHandle == NULL)//если поток не создан то выход из приложения
{
cout << "Error thread!";//вывод сообщения о ошибке
exit(0);//выход из программы
}
//else
//ResumeThread(ThreadHandle[i]);//иначе "будим" поток
}
WaitForMultipleObjects(argc - 1, ThreadHandle, TRUE,INFINITE);//функция ожидания всех потоков
EndTime = clock();//записываем текущее время что бы посчитать время обработки
cout << endl << "Vremya obrabotki : " << EndTime - StartTime << " ms"
<< endl;

И выводит сообщения о времени обработки. Хотя должна ждать завершения созданных потоков...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






А создаются потоки у тебя? Ты проверял? Вот так, например:

       for (int i = 1; i <= argc - 1; i++)//цикл от 1 до кол-ва указанных файлов
{
ThreadHandle[i] = CreateThread(NULL,0, LPTHREAD_START_ROUTINE(
ThreadFunction), argv[i], CREATE_SUSPENDED,&ID[i]);
if (ThreadHandle == NULL)//если поток не создан то выход из приложения
{
cout << "Error thread!";
exit(0);
}
else {
ResumeThread(ThreadHandle[i]);// "будим" поток
cout << "thread #" << i << " was resumed" << endl; // <--- !!!
}
}
Файл-результат нормально создается? Переоткрывается нормально? У меня была проблема с его созданием, пока не перешел на Юникодные символы в имени, или на кириллицу (лучше - второе... Надежнее).
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Бывалый
***

Группа: Пользователи
Сообщений: 222
Пол: Мужской
Реальное имя: Andrew

Репутация: -  0  +


Вот дело в том, что в однопоточной программе с тем же алгоритмом файл создается.а в многопоточной - нет, даже из потока информацию не выводит ничего.

Добавлено через 2 мин.
сделал вот так вот :
for (int i = 1; i <= argc - 1; i++)//цикл от 1 до кол-ва указанных файлов
{
ThreadHandle[i] = CreateThread(NULL,0, LPTHREAD_START_ROUTINE(
ThreadFunction), argv[i], CREATE_SUSPENDED,&ID[i]);//запуск функции на обработки файла,argv[i] - имя файла
if (ThreadHandle == NULL)//если поток не создан то выход из приложения
{
cout << "Error thread!";//вывод сообщения о ошибке
exit(0);//выход из программы
}
else
{
ResumeThread(ThreadHandle[i]);//иначе "будим" поток
cout << "# " << i << " ID " << ID[i] << " HANDLE " << ThreadHandle[i];
}
}




Код
C:\storage\programming\workspace\dB\Debug>db C:\1\1.txt C:\1\2\.txt
# 1 ID 976 HANDLE 0x7dc# 2 ID 964 HANDLE 0x7d8
Vremya obrabotki : 0 ms

C:\storage\programming\workspace\dB\Debug>

вывод на лицо. не понятно..файл опять не создается...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Гость






Значит, ставь вывод информации в каждой строке функции потока, и проверяй, куда выполнение доходит, а куда - нет... После каждой функции опять же проверяй код возврата (GetLastError, если это WinAPI, если нет - то в STL тоже есть возможность проверить, как завершился вызов функции, удачно или нет). Где-то у тебя что-то сбивается, и из-за ошибки выполнение функции потока прекращается.
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Бывалый
***

Группа: Пользователи
Сообщений: 222
Пол: Мужской
Реальное имя: Andrew

Репутация: -  0  +


Я писал где сбивается, в самом первом посте, в листинге, после парсинга строки на слова тупить начинает.

DPos = 0;//обнуляем позицию разделителя
cout << endl << "Before" << endl;
for (size_t i = 0; i < dcount + 1; i++)//цикл чтения слов из целой строки
{
DPos = filestring.find(d);//запоминаем позицию пробела
buffer.append(filestring, 0, DPos);//записывает слово в спомогательную строку
filestring.erase(0, DPos + 1);//удаляем записанное слово
ArrayOfWords.push_back(buffer);//записываем слово в массив-вектор
buffer.clear();//очищаем строку
}
cout << endl << "After" << endl;


Результат.... :
Код
C:\storage\programming\workspace\dB\Debug>db C:\1\1.txt

Vremya obrabotki : 0 ms

C:\storage\programming\workspace\dB\Debug>db C:\1\1.txt


Vremya obrabotki : Before
0 ms

C:\storage\programming\workspace\dB\Debug>db C:\1\1.txt

Vremya obrabotki : 0 ms

C:\storage\programming\workspace\dB\Debug>db C:\1\1.txt

Vremya obrabotki : 0 ms

C:\storage\programming\workspace\dB\Debug>db C:\1\1.txt

Vremya obrabotki : 0 ms

Before

C:\storage\programming\workspace\dB\Debug>db C:\1\1.txt

Vremya obrabotki : 0 ms

C:\storage\programming\workspace\dB\Debug>db C:\1\1.txt

Vremya obrabotki : 0
ms
Before

C:\storage\programming\workspace\dB\Debug>


Добавлено через 4 мин.
Плюс меня волнует то, что у тебя, Volvo, программа-то работает корректно(хотя бы создает рез. файлы), а у меня...
Плюс ещё, поставил в цикле обработки вывод строки buffer...
	for (size_t i = 0; i < dcount + 1; i++)//цикл чтения слов из целой строки
{
DPos = filestring.find(d);//запоминаем позицию пробела
buffer.append(filestring, 0, DPos);//записывает слово в спомогательную строку
filestring.erase(0, DPos + 1);//удаляем записанное слово
cout << endl << "Buffer string" << buffer << endl ;
ArrayOfWords.push_back(buffer);//записываем слово в массив-вектор
buffer.clear();//очищаем строку
}

а результат .. :
Код
C:\storage\programming\workspace\dB\Debug>db C:\1\1.txt
BeforeVremya obrabotki :

Buffer stringIf
0 ms
Buffer stringyou

C:\storage\programming\workspace\dB\Debug>db C:\1\1.txt
Vremya obrabotki : 0 ms

Before

C:\storage\programming\workspace\dB\Debug>db C:\1\1.txt

Vremya obrabotki : 0 ms

Before

Видимо что-то не так с обработкой..Но я никак не могу понять почему.. если создается один поток всего, для 1го файла, и он его должен обрабатывать..ведь все прекрасно работает в однопоточной программе, а функция потока таже самая, просто вызывается последовательно, если файлов >1..

Добавлено через 5 мин.
О, а если убрать вывод сообщения о прошедшем времени, то вообще перестает что либо выводить...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Гость






Так... Более детальное рассмотрение твоего кода выявило еще один недочет: у тебя WaitForMultipleObjects ждет чего? Ты нулевой поток создавал вообще, чтоб ждать его завершения? smile.gif Вот так надо:

string rezfilename = "result";

int main(int argc, char *argv[])
{
InitializeCriticalSection(&Crit);
DWORD ID[10];
HANDLE ThreadHandle[10];

char s[3] = {0};
sprintf(s, "%d", argc - 1);
rezfilename += s[0];
rezfilename += ".txt";

StartTime = clock();
if (argc < 2 || argc > 11) {
cout << "Ne verno vvedeni parametry zapuska!";
exit(0);
}

// читаем файлы
for (int i = 0; i < argc - 1; i++) {
ThreadHandle[i] = CreateThread(NULL,0, LPTHREAD_START_ROUTINE(
ThreadFunction), argv[i + 1], CREATE_SUSPENDED,&ID[i]);
if (ThreadHandle == NULL) {
cout << "Error thread!";
exit(0);
}
else {
ResumeThread(ThreadHandle[i]); // "будим" поток
char s[256] = {0};
sprintf(s, "thread #%d was resumed\n", i);
cout << s;
}
}
WaitForMultipleObjects(argc - 1, ThreadHandle, TRUE, INFINITE); // ждем завершения потоков
EndTime = clock();//записываем текущее время что бы посчитать время обработки
cout << "\nVremya obrabotki : " << EndTime - StartTime << " ms";
DeleteCriticalSection(&Crit);
return 0;
}

У меня этот код прекрасно отрабатывает все 3 (я делал для трех) файлов...
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 20.04.2024 13:55
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name