Поиск количества слов в строке - C (СИ)
Формулировка задачи:
Доброго времени суток. Нужна помощь. Сделал программу сервер для поиска количества слов в строке на С+. Всё бы хорошо, но мне нужно перевести его в чистый С. В Си я плохо разбираюсь. Вот собственно коды:
1) Для сервера
2) Для клиента
#include <winsock2.h>
#include <stdio.h>
#include <string.h>
/*Функция вычисления количества слов в строке.
Так как в принимаемой строке, вместо символа '\0'(конец строки),
идет символ перевода строки('\n'), мы заменяем его на '\0'
*/
int get_word_count (char* str)
{
int result = 0;
for (char* ch = str; *ch != NULL; ch++)
{
if(*ch == '\n')
{
*ch = '\0';
break;
}
//если символ не пробел,
//а следующий символ пробел или перевод строки,
//то нашли слово
if ( *ch != ' ' && ( *(ch + 1) == ' ' || *(ch + 1) == '\n' ) )
result++;
}
return result;
}
int main()
{
WSADATA wsa_data; //структура содержит информацию о проинициализированной нами версии WinsockAPI
int new_socket; // новый сокет полученный после accept
int send_result; // результат для отправления данных
SOCKET listen_socket = INVALID_SOCKET; // сокет
sockaddr_in hints; // структура с информацией о подключении
char rec_buf [512]; // буфер для отправки сообщения серверу
char send_buff [512];// буфер для принятия сообщения от сервера
int result;
result = WSAStartup (MAKEWORD (2, 2), &wsa_data); // инициализация WinSock
if (result != 0) // проверка ошибок
{
printf ("WSAsturtup filed with error %d\n", result);
return 1;
}
memset (&hints, 0, sizeof (sockaddr_in)); //обнуление структуры hints
hints.sin_family = AF_INET; //передача с использованием стека протоколов TCP/IP
hints.sin_port = htons (5050); //порт
hints.sin_addr.s_addr = inet_addr ("192.168.1.133"); // ip адрес
listen_socket = socket (AF_INET, SOCK_STREAM, 0); // создание сокета
if (listen_socket == INVALID_SOCKET) //проверка ошибок
{
printf ("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup ();
return 1;
}
result = bind (listen_socket, (sockaddr*) &hints, sizeof (sockaddr)); // привязка созданного сокета к определённым IP-адресам и портам
if (result == SOCKET_ERROR)//проверка ошибок
{
printf ("bind failed with error %d\n", WSAGetLastError ());
closesocket (listen_socket);
WSACleanup ();
return 1;
}
result = listen(listen_socket, SOMAXCONN); //перевода сокета в состояние прослушивания
if (result == SOCKET_ERROR)//проверка ошибок
{
printf ("listen failed with error %d\n", WSAGetLastError ());
closesocket (listen_socket);
WSACleanup ();
return 1;
}
new_socket = accept (listen_socket, NULL, NULL); // когда сокет находится в состоянии прослушивания (listen) необходимо отслеживать поступление входящих соединений
closesocket (listen_socket); // этот сокет больше не нужен, работаем с new_socket
do
{
result = recv (new_socket, rec_buf, 512, 0); //ждем сообщения от клиента
if(result > 0) //если количество принятых байт > 0, значит клиент прислал сообщение
{
printf ("bytes recieved %d\n ", result); // выводим количество принятых байт
int word_count = get_word_count (rec_buf); // вычисляем длину строки
if (strcmp (rec_buf, "exit") == 0) // если строка равна exit выходим из цикла
break;
sprintf (send_buff, "%d", word_count); // копируем полученное значение длины строки, в передаваему строку
send_result = send (new_socket, send_buff, word_count, 0); //отправляем клиенту длину строки
if(send_result == SOCKET_ERROR)//проверка ошибок
{
printf ("send failed with error %d\n", WSAGetLastError ());
closesocket (new_socket);
WSACleanup ();
return 1;
}
printf ("bytes sended %d\n", send_result); // выводим количество отправленных байт
}
else if(result == 0)
printf ("connection closing\n");
else
{
printf ("recv failed with error %d\n", WSAGetLastError ());
closesocket (new_socket);
WSACleanup ();
}
} while (result > 0);
result = shutdown (new_socket, SD_SEND);
if (result == SOCKET_ERROR)//проверка ошибок
{
printf ("shutdown failed with error %d\n", WSAGetLastError ());
closesocket (new_socket);
WSACleanup ();
return 1;
}
closesocket (new_socket); // закрываем сокет
WSACleanup (); //очищаем wsa
return 0;
}#include <winsock2.h>
#include <stdio.h>
int main()
{
WSADATA wsa_data; //структура содержит информацию о проинициализированной нами версии WinsockAPI
SOCKET connect_socket = INVALID_SOCKET; // сокет
sockaddr_in hints; // структура с информацией о подключении
char send_buffer [512]; // буфер для отправки сообщения серверу
char recv_buffer [512]; // буфер для принятия сообщения от сервера
int result;
int send_result;
result = WSAStartup (MAKEWORD (2, 2), &wsa_data); // инициализация WinSock
if (result != 0) //проверка ошибок
{
printf ("WSAsturtup filed with error %d\n", result);
return 1;
}
memset (&hints, 0, sizeof (sockaddr_in)); //обнуление структуры hints
hints.sin_family = AF_INET; //передача с использованием стека протоколов TCP/IP
hints.sin_port = htons (5050); //порт
hints.sin_addr.s_addr = inet_addr ("192.168.1.133"); // ip адрес
connect_socket = socket (AF_INET, SOCK_STREAM, 0); // создание сокета
if (connect_socket == INVALID_SOCKET) //проверка ошибок
{
printf ("socket failed with error %d\n", WSAGetLastError ());
WSACleanup ();
return 1;
}
result = connect (connect_socket, (sockaddr*) &hints, sizeof (sockaddr_in)); // соединение с сервером
if (result == SOCKET_ERROR) //проверка ошибок
{
printf ( "Unnable to connect to server\n");
closesocket (connect_socket);
WSACleanup ();
return 1;
}
do
{
printf ("Input string: ");
fgets(send_buffer, 512, stdin);
send_result = send (connect_socket, send_buffer, (int) strlen (send_buffer), 0); // отправляем данные серверу
if (result == SOCKET_ERROR) //проверка ошибок
{
printf ("send failed with error %d\n", WSAGetLastError ());
closesocket (connect_socket);
WSACleanup ();
return 1;
}
result = recv (connect_socket, recv_buffer, 512, 0); // ожидаем сообщение от сервера
if (result > 0) // если количество принятых байт > 0, значит сервер прислал сообщение
printf ("String lenght = %s\n", recv_buffer); // вывод сообщение от сервера
else if (result == 0) // если количество принятых байт = 0, значит сервер остановлен
printf ("Connection close\n");
else
printf ("recv failed with error %d\n", WSAGetLastError());
} while (result > 0);
result = shutdown (connect_socket, SD_SEND); // отключаем функцию передачи, все данные были переданы
if (result == SOCKET_ERROR) //проверка ошибок
{
printf ("shutdown failed with error%d\n", WSAGetLastError ());
closesocket (connect_socket);
WSACleanup ();
return 1;
}
closesocket (connect_socket); // закрываем сокет
WSACleanup (); // отчищаем wsa
return 0;
}Решение задачи: «Поиск количества слов в строке»
textual
Листинг программы
for (char* ch = str; *ch != NULL; ch++)
Объяснение кода листинга программы
В данном коде выполняется следующие действия:
str- инициализируется указатель на строку, с которой будет производиться работа.- В цикле
forпроисходит итерация по каждому символу строки, начиная с первого и до последнего. - Условие
*ch != NULLпроверяет, что текущий символ строки не является нулевым символом (т.е. строка не закончилась). - Если условие выполняется, то происходит инкремент указателя
ch, который указывает на следующий символ в строке. - Если условие не выполняется (т.е. текущий символ является нулевым символом), то цикл завершается. Вышеописанный код выполняет поиск количества слов в строке. Каждое слово в строке выделяется символами пробела, а количество слов определяется как количество ненулевых символов в строке минус 1 (т.к. в строке также присутствует нулевой символ).