Wczytanie pliku tekstowego wysupuje program

0

Witam
Mam bardzo dziwny dla mnie problem. Piszę program słownika T9 (ten znany z komórek). Napisałem go pod Linuksem z użyciem GTK i wszystko było ok. Kiedy chciałem go skompilować na Windowsie zaczął się niestabilnie zachowywać. Słowa są zapisywane w pliku tekstowym, wczytywane po kolei i dodawane do struktury danych za pomocą funkcji dodaj_slowo_do_slownika(). Niestety na Windowsie albo fopen zwraca NULL (plik istnieje, sprawdzałem ścieżkę bezwzględną i względną) kiedy za pomocą Visual Studio uruchomię program, albo okienko się włącza i szybko wyłącza (dla plików większych niż 1k, dla mniejszych działa), gdy uruchomię program wchodząc do odpowiedniego folderu. Tak wygląda problematyczna funkcja:

void wczytaj_z_pliku()
{
	FILE *plik;
	char znak;
	char wyraz[50]; /* zakładam maksymalną długość słowa na 50*/
	char *gotowy_wyraz; /*dla niego będę alokował tyle ile potrzeba*/
	int i=0;
	plik = fopen("slowa.txt", "r");
	if(plik!=NULL)
	{
		while(!feof(plik))
		{
			fscanf(plik, "%c", &znak);
			if(feof(plik)) break;
			if(!czy_litera(znak))
			{
				gotowy_wyraz =(char *) malloc((i+1)*sizeof(char));
				wyraz[i]='\0';
				strcpy(gotowy_wyraz, wyraz);
				dodaj_slowo_do_slownika(root, gotowy_wyraz);
				i=0;
				continue;
			}
			else  
			{
				wyraz[i++]=znak;
			}
		}
		fclose(plik);
	}
	else 
	{
		extern GtkWidget * pasek; /*wypisuje w pasku statusu*/
		gtk_statusbar_push( GTK_STATUSBAR(pasek), 0, "Nie udało się załadować pliku słownika");
	}
}

Bardzo proszę o pomoc, jestem załamany tym wszystkim...

0

zawsze sprawdzaj czy malloc poprawnie zaalokował pamięć. może dlatego program się wyłącza.

0
if(i) dodaj_slowo_do_slownika(root, gotowy_wyraz);

Wg mnie to powinno rozwiązać problem.

0

Dzięki za szybkie odpowiedzi.

 if(i) dodaj_slowo_do_slownika(root, gotowy_wyraz);

to niestety nie pomogło...

sprawdzanie, czy poprawnie zaalokowało też nic nie wykryło.
Co do perror to nie wiem, co zrobić, żeby zobaczyć efekt, ponieważ w VS otwiera mi się okienko i nigdzie (chyba) nie widać standardowego wyjścia. Już gotowy program mogę uruchomić z użyciem cmd, ale tam nic nie wypisuje (nawet dla printf)
g_print, który działa normalnie na Linuksie tu nic nie robi...

0

To można uprościć ale błąd szukaj gdzie indziej:

void wczytaj_z_pliku()
  {
   FILE *plik;
   char wyraz[50],znak;
   int i=0;
   plik=fopen("slowa.txt","r");
   if(plik)
     {
      while(fscanf(plik,"%c",&znak)==1)
        {
         if(!czy_litera(znak))
           {
            wyraz[i]='\0';
            if(i) dodaj_slowo_do_slownika(root,strdup(wyraz));
            i=0;
           }
         else wyraz[i++]=znak;
        }
      fclose(plik);
     }
   else 
     {
      extern GtkWidget * pasek; /*wypisuje w pasku statusu*/
      gtk_statusbar_push( GTK_STATUSBAR(pasek), 0, "Nie udało się załadować pliku słownika");
     }
  }

Ba może sprawdź ten poprawiony, ma szanse zadziałać :D

2

chłopaki, nie kibicowaliście naszym i odpadliśmy ;)
a co do problemu ze słowniczkiem to nie mam zielonego pojęcia

0

@_13th_Dragon Niestety Twój uproszczony kod nie pomógł. Na razie program jakoś zaczął działać przy uruchomieniu spod Visual Studia (lokalizacją domyślną dla programu nie było miejsce, gdzie znajdował się plik exe, pewnie nie rozumiem jak dokładnie działa VS). Dzięki za dotychczasowe odpowiedzi, będę jeszcze szukał błędu, bo być może nie leży on w tym miejscu.

0
  1. Program prawdopodobnie będzie dawał możliwość edycji słownika. W takim wypadku polecam trzymać plik słownika w katalogu użytkownika:
    %APPDATA%/nazwa_twojej_aplikacji/slowa.txt na windzie.
    ~/.nazwa_twojej_aplikacji/slowa.txt na niksach.

  2. Nie zabezpieczasz się przed pustymi i zbyt długimi słowami. Również nie dodajesz do słownika ostatniego słowa.

#define MAX_WORD_LEN 50

char word[MAX_WORD_LEN + 1];
int word_len = 0;
int c;
int at_word, was_at_word = 0;

do {
    c = fgetc(plik); // fgetc zwraca -1 jeśli znak nie mógł być wczytany (koniec pliku lub błąd IO), stąd "c" musi być int'em
    at_word = (c >= 0 && czy_litera(c));

    if (at_word) {
        if (word_len < MAX_WORD_LEN) {
            word[word_len++] = c;
        }
    } else if (was_at_word) {
        word[word_len] = '\0';
        word_len = 0;
        dodaj_slowo_do_slownika(root, strdup(word));
    }

    was_at_word = at_word;
}
while (c >= 0);

1 użytkowników online, w tym zalogowanych: 0, gości: 1