배열 쉬프트 관련 질문입니다.

익명 사용자의 이미지

i번째 클라이언트가 나가면 i번째 배열값을 없애고 그 뒤의 값들을 앞쪽으로 당겨오는걸 해보고 있는데
나가는 순서가 바뀔때마다 중간에 공백이 하나 생기네요
어떤식으로 바꿔야하나요..?

for (int i = 0; i < client_list.size(); i++)
	{
		if (client_list[i] == socket)
		{
			//user_ip = m_user_list[i].Ip_Address;
			//AfxMessageBox(user_ip);
 
			DisConnectInfo_str.Format("IP : %s 가 종료했습니다. \n", m_user_list[i].Ip_Address);
			DisConnectInfo_str2.Format("IP : %s\n", m_user_list[i].Ip_Address);
			//DisConnectInfo_str.Format("접속 종료 IP : %s, Port : %d\n", inet_ntoa(dlg->FromClient.sin_addr), dlg->client_addr.sin_port);
 
			dlg->m_ListChat.AddString(DisConnectInfo_str);
			dlg->m_ListClient.DeleteString(dlg->m_ListClient.FindString(-1, DisConnectInfo_str2));
 
 
			for (int j = 0; j < client_list.size(); j++)
			{
				if (client_list[j] == socket)
				{
					strcpy(m_user_list[j].Ip_Address, "");
				}
				m_user_list[j] = m_user_list[j + 1];
				strcpy(m_user_list[j + 1].Ip_Address, "");
			}
		}
 
	}
l595659의 이미지

i번째걸 지우고 당겨야해서

strcpy(m_user_list[i].Ip_Address, "");
m_user_list[i] = m_user_list[i+1];
strcpy(m_user_list[i + 1].Ip_Address, "");

이렇게도 바꿔보고
std::vector<SOCKET>::iterator iter = client_list.begin();
	for (int i = 0; i < client_list.size(); i++)
	{
		if (client_list[i] == socket) //clnt_list[i]의 값이 sock과 같을 때
		{
			client_list.erase(iter); //clnt_list의 첫번째 원소 반복자를 제거
 
			strcpy(m_user_list[i].Ip_Address, "");
			memmove(m_user_list[i].Ip_Address, m_user_list[i + 1].Ip_Address, sizeof(m_user_list));
 
			break;
		}
		iter++;
	}

이렇게도 해봤는데 이건 순서대로는 나가지는데 중간에 들어온거부터 나가면 벡터에 있는 소켓까지 그냥 다 날려버리네요...
swish95의 이미지

client_list 를 이용해서 반복문을 실행하는 루프안에
client_list 를 다시 수정하는건 해서는 안되는 행위입니다.

차라리 해당 인덱스 부터 뒤에거를 앞으로 복사하고(end -1 일땐 제외) 루프 밖에서 마지막껄 지우시는걸 추천합니다.

------------------------------------------------------------
ProgrammingHolic

l595659의 이미지

말씀해주신거 참고해서 변경해보겠습니다.

라스코니의 이미지

아래 사항을 점검해 보시기 바랍니다.

1. list, vector, map 같은 STL 중에서 왜 vector를 사용해야 하는가? 구현하려는 기능에 vector가 가장 최적화되어 있는 STL 객체인가?
2. vector 객체를 쓰면서 왜 client_list 와 같은 혼동을 줄 수 있는 이름을 사용해야 하는가?
3. for() 문에서 i와 iter를 별도로 사용해야할 필요성은 무엇인가?
4. 구현시 웹에서 찾을 수 있는 예제로부터 시작해 보았는가?

l595659의 이미지

말씀해주신 부분 검토해보겠습니다 감사합니다

익명 사용자의 이미지

1. vector를 쓰는 건 뭐 좋습니다.

vector는 원래 시퀀스의 한가운데에서 삽입/삭제가 자주 이루어지는 상황에 적절한 컨테이너는 아니긴 합니다.

하지만 뭐, 주어진 상황에서 client_list는 접속한 클라이언트 숫자만큼의 크기를 가질 텐데, 커 봐야 얼마나 크겠어요?
클라이언트가 접속 끊고 나가는 상황은 또 얼마나 자주 있겠습니까.

2. i에 대해 돌아가는 루프 안에 j에 돌아가는 루프가 있는 게 이상하지 않아요?

로직을 잘 고민해보면 이게 애초에 이중 루프를 쓸 문제가 아니라는 점을 깨닫게 될 겁니다.

3. C++를 쓴다면 C++에 맞게.

m_user_list[i].Ip_Addressstrcpy를 쓰시는 걸 보니 C-style 문자열인 듯 한데, 그런 거 C++에서 사용하는 건 웬만하면 지양하세요.

std::string이든 CString이든 (MFC 맞죠?) 쓰는 게 편합니다.

4. STL를 쓴다면 STL에 맞게.

STL 시퀀스 컨테이너에서 원소를 삭제할 때는 Erase–remove idiom이 주로 쓰였습니다.

https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom

위키피디아 항목을 보고 오셨다면 아시겠지만, C++20부터는 그냥 std::erase 쓰셔도 됩니다.

https://en.cppreference.com/w/cpp/container/vector/erase2

세상 참 좋아졌어요. 그렇지 않습니까?

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.