GtkTextView 의 GtkTextBuffer 에 관한 질문입니다.

freedom의 이미지

제가 GtkTextBuffer에 insert 혹은 Set Text 를 위해

gtk_text_buffer_insert(textbuffer, &end, buffer, strlen(echoBuffer));

gtk_text_buffer_set_text(textbuffer, str, -1);

를 이용해서 작업을 했었습니다.

여기서

textbuffer 는 GtkTextBuffer*

buffer, str 등은 gchar* (UTF-8) 로 변환했음

gchar buffer[6000]; 등
gchar* str = (gchar*)g_malloc(6000);

이용했습니다...

buffer, str같은 문자열의 길이가 짧으면 잘 됩니다.
(저의 경우 xxx.c 같은 소스 파일을 읽어와 TextBuffer 에 넣었습니다.)
하지만 8000라인 이상일 경우 (제가 테스트 해본 C파일, 컴파일은 오류 없이 잘되던 소스)

(project3:20258): Gtk-CRITICAL **: gtk_text_buffer_insert: assertion `text != NULL' failed

와 같은 에러가 나옵니다..
buffer, str 등은

if((fp = fopen(file_name, "r")) == NULL)
{
g_print("file open failed !!!\n");
return;
}

while(fgets(buffer, sizeof(buffer), fp))
{
gtk_text_buffer_get_end_iter(textbuffer, &end);
gtk_text_buffer_insert(textbuffer_compile, &end,
g_locale_to_utf8(echoBuffer,-1, NULL,NULL,NULL),
strlen(echoBuffer));
}

위 소스 처럼 file로 부터 읽어 서 처리를 했습니다.

참고로 buffer 의 사이즈는 6000 입니다.

위 와 같은 소스로 8000 라인 정도의 c파일을 TextBuffer 에 넣는 작업을 할경우

위에서 보인 오류가 5번정도 일어납니다. 여러번 해본 결과 똑같이 5번 일어나더군요..

오류가 날때 g_print 등으로 출력을 해보면 (null) 이 나올뿐 무슨 문제인지 모르겠습니다.
(오류가 일정한 부분에서 나서 그 부분을 계산해서 출력문을 넣었습니다.)

사실 파일에서 6000정도의 버퍼로 읽기 때문에 테스트 c파일안에 공백이 많다해도 null 이 될순 없다고

생각합니다..

fopen 말고 open 함수로도 테스트 해본 결과 같았습니다.

if((fp = open(file_name, O_RDONLY)) < 0)
{
g_print("open failed\n");
}

while( total != file_size )
{
// bytesRead 라는 변수로 얼만큼 읽어 왔는지 g_print 등으로 확인도 해봤는데 역시나 읽는건 정해진
// 만큼 읽어오지만 막상 TextBuffer 에 넣을때는 오류가 납니다.
bytesRead = read( fd, echoBuffer, 6000);
total += bytesRead;
gtk_text_buffer_get_end_iter(textbuffer, &end);
gtk_text_buffer_insert(textbuffer, &end
, g_locale_to_utf8(echoBuffer,-1, NULL,NULL,NULL), -1);
bzero( echoBuffer, sizeof(echoBuffer) );
}

그리고 insert, set_text 함수의 마지막 파라미터 값을 제가 이해 하기론 문자열의 길이로 알고 있는데

strlen() 이나 sizeof() 등보다는 예문에서의 -1 로야 그나마 성공률이 높았습니다..

sizeof() 는 buffer 등이 gchar* 포인터가 아니라 배열일 경우에만 사용했습니다.

어쩌면 특정 문자같은 경우에 이러한 오류가 일어나는 하는 추측은 해보는데 출력조차 안되니

디버깅을 조차 힘든 상황입니다. 혹시나 운이 없어서 gchar* buffer 의 처음 index 에 null 에 해당하는

문자가 들어가서 그런것은 아닐까 하는 억측도 해봤지만.... 이건 좀 오버 같고

도대체 뭐가 문제인지 모르겠군요..

작은 힌트라도 좋습니다.

많은 조언 부탁드립니다.

익명사용자의 이미지

제 예상으로는 g_locale_to_utf8 함수가 실패해서 NULL 값이 들어가는 것으로

보입니다. g_locale_to_utf8 의 마지막 인자(GError)로 무슨 에러가 발생했는지

확인해보세요. 그리고 g_locale_to_utf8 함수 반환 값을 g_free 해주셔야 됩니다.

아니면 메모리 누수가 날겁니다.

마지막으로 gtk_text_buffer_insert 마지막 인자를 -1로 넣으면 nul terminator 까지

처리해준다고 하네요.

자세한 건 api reference 참고하시면 되겠습니다.

freedom의 이미지

g_locale_to_utf8 의 마지막 파라미터 GError 로 확인결과

"Invalid byte sequence in conversion input"
"변환 입력에서 잘못된 바이트 순서"

라고 나옵니다.. 단지 추측되는건 한글이 아닌

알수 없는 깨진 문자들이 들어 갈경우 이렇게 되는듯합니다. 그외 경우는 아직 못찾았습니다.

무엇보다 위 메시지의 정확한 의미를 모르게군요

keizie의 이미지

소스 파일이 이미 UTF-8로 작성되었으면 변환 과정에 에러가 나겠죠. (자동으로 넘어가던가 모르겠네요)

freedom의 이미지

kz 님 말씀에 따라 텍스트 에디터를 Visual studio (습관) 써서 그럴지도 모른다는 생각이 들었습니다.

그래서

g_convert(str->str, -1, "UTF-8", "ISO-8859-1",NULL,NULL,NULL);

이용해서 문제는 해결했습니다.

아직 원천적인 해결은 하지 못했습니다만, 추후 해결된다면 다시 한번 글 올리겠습니다.

답변 감사드립니다 (__)

댓글 달기

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