2011-02-20 4 views
0

gtk + 및 gtksourceview-2.0과 함께 C 언어를 사용하여 프로그램을 작성하고 있습니다.c gtk + : GtkSourceView의 TextBuffer에 텍스트 파일로드

내용을 내가 파일을 선택하는 사용자에 대한 GtkFileChooser을 사용하고 있는데 그가 그것을 클릭 할 때, 내가 원하는이 GtkSourceView 'TextBuffer에로드 할

이 사용자가 실행됩니다 기능입니다 내가 t에 세그먼트 오류를 ​​얻을 후 후

** (tour_de_gtk:18107): DEBUG: /home/ufk/Projects/gtk-projects/tour-de-gtk/Debug/src/examples/example_gtk_label/main.c is chosen 

** (tour_de_gtk:18107): DEBUG: file size: 16 

** (tour_de_gtk:18107): DEBUG: after fread 

:

void on_file_activated(GtkWidget *widget, gpointer data) { 
    GFile *file; 
    FILE *fp; 
    gchar *path_name; 
    long file_size; 
    gchararray file_buffer; 
    file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(widget)); 
    path_name=g_file_get_path(file); 
    g_debug("%s is chosen\n", path_name); 
    fp=fopen(path_name, "r"); 
    g_assert(fp != NULL); 
    fseek(fp, 0L, SEEK_END); 
    file_size = ftell(fp); 
    rewind(fp); 
    g_debug("file size: %ld\n",file_size*sizeof(gchar)); 
    file_buffer=calloc(file_size, sizeof(gchar)); 
    g_assert(file_buffer != NULL); 
    fread(&file_buffer,file_size,1,fp); 
    g_debug("after fread"); 
    //file_buffer[file_size*sizeof(gchar)]=0; 
    //g_debug("after adding zero: %s",file_buffer); 
    gtk_text_buffer_set_text (textbuffer, file_buffer,2); 
    g_debug("after set text"); 
    g_object_unref(file); 
} 

이 내 응용 프로그램의 출력입니다 : 더블 클릭은 GtkFileChooser에있는 파일입니다 그는 gtk_text_buffer_set_text 명령을 사용합니다.

내가 볼 수 있듯이 주석 처리 된 두 개의 명령이 있습니다. g_debug 분명히 내가 문자열의 끝에 0을 추가하지 않았기 때문에 세그먼트 오류를 ​​생성하는 버퍼를 시도하고 심지어 문자열의 끝에 0을 추가하려고하면 세그먼트 오류가 발생합니다. 나는 아마 뭔가 잘못 했어.

여기 버퍼의 처음 두 문자 만 쓰려고하는데 행운이 없습니다.

어떤 아이디어가 있습니까?

갱신

완성 기능 : 가능한 많은 개선이 여기에있다

void on_file_activated(GtkWidget *widget, gpointer data) { 
GFile *file; 
gchar *path_name; 
long file_size; 
gchar *file_buffer; 
GError *error; 
gboolean read_file_status; 
file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(widget)); 
path_name=g_file_get_path(file); 
g_debug("%s is chosen\n", path_name); 
read_file_status=g_file_get_contents (path_name,&file_buffer,NULL, &error); 

if (read_file_status == FALSE) { 
    g_error("error opening file: %s\n",error && error->message ? error->message : "No Detail"); 
    return; 
} 
gtk_text_buffer_set_text (textbuffer, file_buffer,-1); 
g_debug("after set text"); 
g_object_unref(file); 
} 

답변

2

, 이미 많은 것을 알고 그냥 장난 될,하지만 난 경우에는 여러 목록을 것입니다 수 있습니다.

gchararray file_buffer;

그냥 문자 *

g_assert 사용 (FP를 = NULL를!)

, 그래서 여기에 g_printerr (오류 런타임) 또는 대화 상자가 더 나은

fseek과 (FP, 0L, SEEK_END) 될 수 없습니다 프로그래밍 오류를 주장 사용해야; file_size = ftell (fp); 되감기 (fp);

함수 fstat (fileno (FP), & statbuf는) 아마이 할 수있는 더 좋은 방법이지만, 전체적인 접근 방식은 가지 나쁜; 크기를 얻는 대신 동적으로 증가하는 버퍼를 읽는 것이 좋습니다. 또는 전체 버퍼를 미리 할당하려는 경우 g_file_get_contents()를 사용하십시오. 또 다른 방법은 g_file_query_info()이다 (기타 휴대용이고 사용 VFS)

file_buffer은 calloc = (FILE_SIZE,는 sizeof (gchar을));

g_new0 (char, file_size)가 더 좋거나 g_malloc0 (file_size)입니다. 또한 널 바이트를위한 공간을 만들기 위해 file_size + 1이 필요합니다.

fread (& file_buffer, file_size, 1, fp);

여기서는 & file_buffer (char **) 대신 file_buffer (char *)를 원합니다. 이것은 아마도 즉각적인 파손의 실제 원인 일 것입니다.

또한 fread()의 반환 값을 확인해야합니다.

가 또한 여기에없는 것은에서 읽은 데이터에 g_utf8_validate()입니다.

는 g_file_get_contents의 구현에서보세요() 여기에 한 가지 방법을 볼 수 있습니다. g_file_load_contents를 사용하여 경로 (휴대용, vfs 사용) 대신 GFile을 사용하거나 실제 응용 프로그램 인 g_file_load_contents_async()를 사용하는 것이 더 좋습니다. 디버그 세그먼테이션 폴트 (segfault)으로

, 가장 멋진 두 도구는 다음과 같습니다 GDB에서

  • 실행, 충돌 기다린 다음 "BT"를 입력; 당신이 Valgrind의에서
  • 실행을 컴파일 할 때 당신이 나쁜 메모리에
+0

덕분에이 전체 답변을 많이 볼 말한다 곳, 참조 컴파일러와 -g 사용하십시오. 나는 gtk +에 익숙하지 않고 여전히 혼란 스럽습니다. 여기 작성한 모든 팁은 저에게 매우 중요합니다. 당신의 의견을 테스트하고 나중에 돌아올거야. – ufk

+0

덕분에 최종 기능으로 내 메인 포스트를 업데이트했습니다. 당신이 제공 한 모든 조언에 감사드립니다. – ufk

+0

cool. 당신은 아마 여전히 g_utf8_validate()를 원할 것입니다. 누군가 latin-1 파일이나 다른 것을 열려고한다면 충돌을 일으킬 수 있습니다. –