Marta Ś.

Marta Ś. Grafik komputerowy

Temat: Proszę o pomoc

Witam wszystkich!

Piszę program w języku C. Potrzebuję pomocy w operacjach na pliku. Mianowicie mam w pliku tekstowym wpisać pytania i prawidłową odpowiedz. Następnie w programie ma wczytać pierwsze pytanie i czekać na podanie odpowiedzi. Następuje sprawdzanie czy podana odpowiedź zgadza się z podaną wcześniej. Jeśli odpowiedz jest prawidłowa,
następuje wczytanie drugiego pytania, jeśli nie, zamknięcie programu itd.
Ma być możliwość zmiany, lub dopisania pytania z zastrzeżeniem, że nie ma być nic zmieniane w kodzie źródłowym. Jak nastąpią jakieś zmiany to tylko z poziomu pliku tekstowego.

Bardzo proszę o pomoc.
Jakub L.

Jakub L. Programista

Temat: Proszę o pomoc

Co prawda jest to dokumentacja do C++, ale wygląda ok: http://www.cplusplus.com/reference/clibrary/cstdio/FILE/
Marta Ś.

Marta Ś. Grafik komputerowy

Temat: Proszę o pomoc

Powiem jak wygląda plik tekstowy: w nieparzystych wierszach mam pytania natomiast w parzystych poprawne odpowiedzi. Nie wiem jak wykonać warunek sprawdzania poprawnej odpowiedzi.
Jakub L.

Jakub L. Programista

Temat: Proszę o pomoc

http://www.cplusplus.com/reference/clibrary/cstring/st...

Pamięć to malloc i free, stringi kończą się zerem, więc muszą mieć długość większą o 1 od liczby znaków. Memset jest przydatny.

konto usunięte

Temat: Proszę o pomoc

Marta Śmigielska:
Powiem jak wygląda plik tekstowy: w nieparzystych wierszach mam pytania natomiast w parzystych poprawne odpowiedzi. Nie wiem jak wykonać warunek sprawdzania poprawnej odpowiedzi.

Jeśli to ma być w C, to i tak nie ma co panikować - program będzie naprawdę prosty. Zobacz sobie fopen(), fread(). (Fscanf też byłby ok, ale nie pchajmy się w to). Co robisz:
- otwierasz plik,
- czytasz z niego jakąś liczbę bajtów (w szczególności 1 bajt - buforowanie i tak jest załatwione pod freadem), dopóki nie trafisz na \n (lub \r\n jeśli korzystasz z jakiegoś egzotycznego systemu) wyświetlasz na ekran - to jest pytanie.
- czytasz odpowiedź z konsoli - scanf
- czytasz znów do entera z pliku i sprawdzasz czy znaki są takie same jak odpowiedź.

konto usunięte

Temat: Proszę o pomoc

Poniewaz kiedys pisalem cos niemal identycznego, to swietnym ulatwieniem jest: strcasecmp

konto usunięte

Temat: Proszę o pomoc

To fakt, ale nie ma go w ANSI, więc nie na każdym kompilatorze będzie. Ja bym jednak stawiał na coś w rodzaju:

http://www.merriampark.com/ldc.htm

:)
Ale trzeba by sprawdzić czy dobrze tutaj jest zaimplementowane. No i raczej jednak nie w tym projekcie. Pozostałbym przy strcmp.
Aleksander W.:
- czytasz z niego jakąś liczbę bajtów (w szczególności 1 bajt - buforowanie i tak jest załatwione pod freadem), dopóki nie trafisz na \n (lub \r\n jeśli korzystasz z jakiegoś egzotycznego systemu) wyświetlasz na ekran - to jest pytanie.

Jednak czytałbym fgetsem. Będzie prościej. Na pewno w projekcie można założyć ograniczenie na długość linii. ;)Adam Michalski edytował(a) ten post dnia 27.09.10 o godzinie 10:50
Piotr P.

Piotr P. Software Developer

Temat: Proszę o pomoc

http://library.gnome.org/devel/glib/unstable/glib-Key-...

* skompiluje się chyba wszędzie (może nie na kalkulatorze)
* pytania mogą być wyświetlone po polsku lub japońsku
* zero roboty z obsługą pliku
* banalna edycja pliku tekstowego z pytaniami i odpowiedziami
Marta Ś.

Marta Ś. Grafik komputerowy

Temat: Proszę o pomoc

#include <stdio.h>
#include<conio2.h>

int main()
{
FILE *f;
char tab [100];
char odp[100];
int i;

f= fopen ("plik.txt" , "r");
if (f == NULL) perror ("Error opening file");
else
{
while ( ! feof (f) )
{
fgets (tab , 100 , f);
fputs (tab , stdout);
printf("Podaj odpowiedz:");
scanf("%s",&odp);
[u]if(odp==tab[i+2]) continue;[/u]
else break;
}
fclose (f);
getch();
}
return 0;
}


Mam kod napisany w powyższy sposób. W "podkreślonym" wierszu występuje błąd, z którym nie mogę sobie poradzić. Ogółem nie potrafie napisać pętli, która by spełniała warunek przedstawiony przeze mnie w wcześniejszych postach. Ponownie muszę prosić o pomoc...Marta Śmigielska edytował(a) ten post dnia 27.09.10 o godzinie 15:41

konto usunięte

Temat: Proszę o pomoc

if(odp==tab[i+2]) continue;

To co napisałaś oznacza mniej więcej "porównaj adres tablicy znaków odp z i+drugą literką w tablicy tab" czyli nie ma to za bardzo sensu, do tego "i" nie jest zainicjalizowane (nie ma żadnej wartości, czy raczej ma dość losową).
Do porównywania dwóch napisów zainteresuj się funkcją strcmp (nagłówek string.h).
Waldemar Kruszka

Waldemar Kruszka Programista
ABAP/C/C++

Temat: Proszę o pomoc

if (strcmp (&odp[0],&tab[0]) != 0){
//odpowiedz poprawna
}
else{
//nie
}

konto usunięte

Temat: Proszę o pomoc

Krzysztof Kawa:
Do porównywania dwóch napisów zainteresuj się funkcją strcmp (nagłówek string.h).

Koleżanka pomyślała intuicyjnie. Dlatego trzeba się uczyć C++ a nie C. ;)
Marta Śmigielska:
scanf("%s",&odp);

To jest niepoprawne. Jeśli scanf, to należy tak:

scanf("%99s", odp);

W twojej wersji, jeśli użytkownik wpisze więcej niż 99 znaków, to będzie klapa.

No i to:
getch();

Jakieś nie ANSIowe dziwadło. Zamiast tego użyj getchar() i pozbądź się tego conio2.h.
Waldemar Kruszka:
if (strcmp (&odp[0],&tab[0]) != 0){

Nie ma potrzeby aż tak komplikować :)


if (strcmp(odp, tab)) {
...
}
Adam Michalski edytował(a) ten post dnia 27.09.10 o godzinie 16:43
Jakub L.

Jakub L. Programista

Temat: Proszę o pomoc

Marta Śmigielska:
#include <stdio.h>
#include<conio2.h>

int main()
{
FILE *f;
char tab [100];
char odp[100];
int i;

f= fopen ("plik.txt" , "r");
if (f == NULL) perror ("Error opening file");
else
{
while ( ! feof (f) )
{
fgets (tab , 100 , f);
fputs (tab , stdout);
printf("Podaj odpowiedz:");
scanf("%s",&odp);
[u]if(odp==tab[i+2]) continue;[/u]
else break;
}
fclose (f);
getch();
}
return 0;
}


Mam kod napisany w powyższy sposób. W "podkreślonym" wierszu występuje błąd, z którym nie mogę sobie poradzić. Ogółem nie potrafie napisać pętli, która by spełniała warunek przedstawiony przeze mnie w wcześniejszych postach. Ponownie muszę prosić o pomoc...

strncmp jest odpowiedzią, ale tam jest więcej błędów:
* na przykład zobacz co będzie jak wpiszesz 200 znaków odpowiedzi;
* albo pytanie będzie miało ogólnie 100 lub więcej znaków;
* tab masz pytanie, żeby odczytać odpowiedź, musisz zrobić kolejny fgets;
* zmienna i ma nieustaloną wartość, więc nie istnieje coś takiego jak i+2;
* a nawet jakby istniała, to z powodu podpunktu 2 tab[i+2] to w najlepszym wypadku byłby jakiś znak z pytania;
* program ma przerywać po pierwszym błędzie?
Jakub L.

Jakub L. Programista

Temat: Proszę o pomoc

Adam Michalski:
Krzysztof Kawa:

if (strcmp(odp, tab)) {
...
}

Tylko trzeba pamiętać że wyłapujemy w ten sposób gdy się różnią.
Mało, cholera, intuicyjne, ileż razy przez to musiałem rekompilować kod po dodaniu != 0 (wiem ze można samo ! ale wolę != 0).

Edit2: i wolałbym jednak strncmp, albo zależne od platformy strnicmp.Jakub L. edytował(a) ten post dnia 28.09.10 o godzinie 09:06

konto usunięte

Temat: Proszę o pomoc

Fakt, strncmp jest bezpieczniejsze. Zdecydowanie.

konto usunięte

Temat: Proszę o pomoc

To nie jest mało intuicyjne, jeśli docenimy, że strcmp itp. funkcje zwracają liczbę mniejszą, równą lub większą niż zero zależnie od tego, czy pierwszy łańcuch jest leksykonograficznie mniejszy, równy lub większy drugiemu.
Jakub L.

Jakub L. Programista

Temat: Proszę o pomoc

Semantyka jest jasna.
Problem w tym, że strcmp i == (jakby == porównywało stringi znak po znaku) działają zupełnie odwrotnie, czyli if (strcmp(s1, s2)) wykona się wtedy gdy if (s1 != s2) i w drugą stronę if (s1 == s2) działa jak if (!strcmp(s1, s2)).
Nie wiem jak inni, ale ja często zapominam o negacji i mnie to wnerwia :(

konto usunięte

Temat: Proszę o pomoc

Przy strcmp akurat preferuję pisanie if(strcmp() == 0) - w kontekście semantyki daje to wyraźną odpowiedź, co się zdarzy. Zero jest zwracane przy równości napisów. Negacja trochę jednak utrudnia czytanie kodu. A łatwe czytanie kodu przez człowieka, to jest to, o co warto dbać - większość czasu i wysiłku traci się właśnie na czytaniu.
Marta Ś.

Marta Ś. Grafik komputerowy

Temat: Proszę o pomoc

Zmieniłam kod i plik tekstowy rozdzieliłam na dwie części. Powstał plik z pytaniami i inny z odpowiedziami.
Kod mi się kompiluje natomiast źle interpretuje warunek i nawet jak podaje prawidłową odpowiedź wypisuje mi "zle" i kończy program.

int main()
{
FILE *f;
FILE *n;
char tab [100];
char podp[100];
int i;
char odp;

f= fopen ("plik.txt" , "r");
n=fopen ("odpowiedzi.txt" , "r");

for (i=0;i<5;i++)
{
fgets (tab , 100 , f);
fgets (podp , 100 , n);
fputs (tab , stdout);

printf("Podaj odpowiedz:");
scanf("%s",&odp);
if(strcmp (&odp,&podp[i]) == 0)
{printf("Dobrze");
getch();}
else if( strcmp (&odp,&podp[i]) != 0);
{ printf("zle"); getch(); break;}
}
fclose (n);
fclose (f);
getch();

return 0;
}


Tak wygląda plik txt z pytaniami:
1. Ile bitow ma bajt?   A. 10   B. 2   C. 8   D. 4
2. Pochodna z X wynosi: A. 1 B. 0 C. 2 D.10
3. Wcisniecie CTRL i jakiej litery oznacza 'wytnij'? A. A B. V C. C D. X
4. Co to jest "lori"? A. kot B.pies C.lemur D. mysz


A tak plik txt z prawidlowymi odpowiedziami:
c
a
d
c


P.S.Program przypomina cos na kształt testu.
Marta Ś.

Marta Ś. Grafik komputerowy

Temat: Proszę o pomoc

[quote]Koleżanka pomyślała intuicyjnie. Dlatego trzeba się uczyć C++ a nie C. ;)[/quote]


Oczywiście, zgadzam się. Narazie jednak jest wymagany ode mnie język c i nic na to nie poradzę...:(

Następna dyskusja:

Proszę o pomoc




Wyślij zaproszenie do