[c++] iterator로 나타내는 구조체의 멤버변수에 값을 어떻게 ?

gusdo2000의 이미지

#include <fstream>
#include <algorithm>
#include <vector>
#include <cctype>
#include <iterator>
#include "sum_c++.h"

using namespace std;




int main()
{
	char str[100];
	string temp;
	vector<student_info> students;
	typedef string::iterator iter;
	typedef vector<student_info>::iterator v_iter;	
	bool choice;

	ifstream read_file("info.txt");
	
	while(!read_file.eof()) //read_file.good()
	{
		choice = false;
		read_file.getline(str,100,'\n');
		temp = str;
		
		iter i = temp.begin();	
		v_iter count = students.begin();
		
		while( i != temp.end() )
		{

			while( i != temp.end() && isspace(*i) )
			               ++i;

			iter j = i;

			while( j != temp.end() && !isspace(*j) )
				++j;

			if( i != j && choice == false)
			{
			1번쨰......	students[count].name = string(i,j);
			2번째......	temp = string(i,j);
				      temp.copy((*count).name, 30);
			3번째......	(*count).name = string(i,j);
				i = j;
				choice = true;
			}
			else if( i != j && choice == true )
			//	students[count].grade = string(i,j);
				temp = string(i,j);

			//cout << "count++ " << count+1 << endl;
			++count;
		}

	}
}

c++ 초보입니다.

위의 프로그램은 파일에서 한 라인씩 값을 읽어와 공백을 기준으로 한 단어씩 나눠 구조체에 저장하는 프로그램입니다.

구조체 형식

struct student_info
{
         std::string name;
         double grade;
} 


네가지 질문이 있습니다.
1. 구조체 배열와 스트링에 대해 index를 쓰지않고 iterator를 사용합니다.
"cout << iterator변수" 로 그 값을 출력하려고 하면 에러가납니다.
왜 그런가요?

2. 공백을 기준으로 뽑아낸 단어를 구조체의 멤버변수 name에 저장하는 방법을 모르겠습니다.
위의 프로그램에서 세가지 방법으로 각각 해보았는데.. 실행이 되자 않고 세그먼트폴트가 됩니다.

3. 파일의 끝에 대한 질문입니다.
이 프로그램을 c로 구현한적이 있는데..
그때도 파일의 끝 문제때문에 고심했었습니다.
c에서 while( read() == EOF ) 대략 이런식으로 구현을 했는데..
EOF를 인식하지 못해서 무한루프를 돌았었습니다.
그래서 ftell을 이용해 파일의 끝위치를 알아내서 그것을 이용해서 비교를 하였습니다.

이번에 c++ 구현시에도 eof() 함수가 있어서 이것을 이용해서 검사를 하는데.. 역시나 파일의 끝을 인식하지 못합니다.
그래서 계속 값을 읽어들이려는 시도를 하는데..
어떻게 해결을 해야하나요?
제가 eof()에 대한 개념을 잘 알지 못하는 것인가요?

4. c++에선 std::string이란 타입이 있습니다.
이것과 캐릭터배열( char a[100]; )과의 차이점을 모르겠습니다.
이 두개가 혼용되어서 사용되는데..
언제 이 둘중 어떤 타입을 사용해야 하는지 잘 구분이 안갑니다.

char str[100];
string temp;
..............

read_file.getline(str,100,'\n');
temp = str;

위의 프로그램에서 getline함수는 std::string의 변수를 인수로 받으면 에러가 나더군요..
[ 원래코드.... read_file.getline(temp,100,'\n'); ]
그래서 위와같은 처리를 해주었습니다.
저는 std::string 타입에서 제공하는 멤버함수를 사용하고 싶었거든요..

c는 c 답게..
c++는 c++ 답게 구현하려고 노력중입니다.
그런데..너무 혼란스럽네요^^;;

amister의 이미지

1. cout << (*iter) 같이 해야 하지 않을지?

2. 어떤것이 문제인지 코드를 테스트해본 것은 아닙니다만... string 은 그냥 assign하면 되기 때문에 다른 쪽에 문제가 있을 것으로 생각됩니다.

공백을 기준으로 단어들을 쉽게 나누는 방법은 다음과 같이 하시면 더 편할 것입니다.

// ex) "foo bar keke" 라는 string을 세조각 내는 코드.
string s = "foo bar keke";
string foo, bar, keke;
istringstream is(s);

is >> foo;
is >> bar;
is>> keke;

제가 아는 간단한 방법입니다. file에서 읽은 데이터를 string으로 만들고 위와 같이 stringstream을 사용하면 편합니다. :)

3. while (!ifstream.readline(...).eof()) { ... } 로 해보심이...

4. std::string은 char[] 를 기반으로 안전하고 편리한 method들을 구현해주는 class라고 생각하시면 됩니다. overflow나 underflow처리가 편하고, copy나 substring, finding... 등등, string에 대해서 생각할 수 있는 것들을 모아놓은 것이죠. 원래는 basic_string<>이 있고, string은 basic_string<char> 입니다.

때문에 대부분의 상황에서는 std::string을 쓰는 것이 코드도 깔끔해지고 버그가 생길 확률도 극히 줄어듭니다. char[]를 바로 다루는 것보다 성능이 떨어질 걱정은 보통 안합니다. 많은 경우 char[]를 유저가 처리하는 것보다 오히려 더 빠르기도 하구요.

따라서 C++로 개발하실 때는 std::string을 최대한 활용하도록 하시고, 부득이하게 char 를 사용해야 할 경우만 std::string.c_str() method를 사용하여 char[] 타입으로 바꾸고 사용하시는 것이 좋다고 생각합니다.

ifstream에서 std::string으로 바로 getline()하는 것도 있습니다. 잘 찾아보세요.

doldori의 이미지

gusdo2000 wrote:
2. 공백을 기준으로 뽑아낸 단어를 구조체의 멤버변수 name에 저장하는 방법을 모르겠습니다.
위의 프로그램에서 세가지 방법으로 각각 해보았는데.. 실행이 되자 않고 세그먼트폴트가 됩니다.

count라는 이름 때문에 인덱스로 착각하셨군요. 이것은 인덱스가 아니라 iterator입니다.
코드를 보면 students라는 빈 vector를 만들고 count가 students.begin()을
가리키게 했는데, 지금 상태로는 count가 널 포인터와 비슷하다고 보시면 됩니다.
그런데 *count로 역참조를 했으니 에러가 납니다. 이런 식으로 해보세요.
student_info aStudent;
aStudent.name = temp(i, j);
students.push_back(aStudent);

사실 temp도 필요가 없어보이는군요. 바로 str을 쓰면 되겠습니다.

gusdo2000 wrote:
3. 파일의 끝에 대한 질문입니다.
이 프로그램을 c로 구현한적이 있는데..
그때도 파일의 끝 문제때문에 고심했었습니다.
c에서 while( read() == EOF ) 대략 이런식으로 구현을 했는데..
EOF를 인식하지 못해서 무한루프를 돌았었습니다.
그래서 ftell을 이용해 파일의 끝위치를 알아내서 그것을 이용해서 비교를 하였습니다.

이번에 c++ 구현시에도 eof() 함수가 있어서 이것을 이용해서 검사를 하는데.. 역시나 파일의 끝을 인식하지 못합니다.
그래서 계속 값을 읽어들이려는 시도를 하는데..
어떻게 해결을 해야하나요?
제가 eof()에 대한 개념을 잘 알지 못하는 것인가요?


eof()는 사실 거의 쓸 일이 없는 함수입니다. 이 함수는 파일 포인터가 파일 끝에
위치하는지 알려주는 함수가 아닙니다. 입력에 실패한 이유가 파일 끝 때문인지
알려주는 것이죠. (입력 실패의 원인이 꼭 파일 끝 때문만은 아니므로.) 즉 입력이
적어도 한 번은 실패를 해야 eof()가 true를 반환한다는 뜻입니다. 그리고 대부분의
경우 입력이 성공했는지 실패했는지 여부가 중요하지 실패의 원인이 파일 끝 때문인지는
알 필요도 없지요. 보통은 이런 식으로 합니다.
ifstream fin;
int i;
while (fin >> i) { /* do something */ }

gusdo2000 wrote:
4. c++에선 std::string이란 타입이 있습니다.
이것과 캐릭터배열( char a[100]; )과의 차이점을 모르겠습니다.
이 두개가 혼용되어서 사용되는데..
언제 이 둘중 어떤 타입을 사용해야 하는지 잘 구분이 안갑니다.

코드:
char str[100];
string temp;
..............

read_file.getline(str,100,'\n');
temp = str;

위의 프로그램에서 getline함수는 std::string의 변수를 인수로 받으면 에러가 나더군요..
[ 원래코드.... read_file.getline(temp,100,'\n'); ]
그래서 위와같은 처리를 해주었습니다.
저는 std::string 타입에서 제공하는 멤버함수를 사용하고 싶었거든요..


istream::getline() 함수의 원형을 보시면 에러가 나는 이유를 알 것입니다.
string을 입력할 때는 이 함수가 아니라 다른 함수를 씁니다.
string word;
read_file >> word;
string line;
getline(read_file, line);

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.