Fórum Ubuntu CZ/SK
Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: Royal 28 Února 2011, 11:21:07
-
Buďte zdrávi,
nevím, jestli toto spadá pod tuto kategorii, a celkově i pod toto fórum, ale mám problém s C.
Mám následující kód:
#include <stdio.h>
#include <stdlib.h>
char *str;
int main()
{
printf("Napis neco:\t");
scanf("%s", &str);
printf("Zadal jsi '%s'.\n", str);
return 0;
}
Program zkompiluju s varováním "scanf.c:9: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’", nicméně zkompiluju.
Spustím ho, něco napíšu, enter a "Neoprávněný přístup do paměti (SIGSEGV)".
Už jsem zkoušel zaměnit "char *str;" za "char *str = malloc(sizeof(char)*30);", ale GCC hlásí chybu.
Taky jsem zkoušel dát na začátek funkce main() "str = malloc(sizeof(char)*30);", ale jako by to tam nebylo, pořád to padá.
Taky musím mít proměnnou str deklarovanou před začátkem funkce main, protože ve složitějším programu, který píšu, využívají tuto proměnnou ještě další funkce.
Co mám do toho kódu ještě napsat nebo co mám změnit, aby to fungovalo, prosím?
Díky
-
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *str = (char*) malloc(30 * sizeof(char));
printf("Napis neco:\t");
scanf("%s", str);
printf("Zadal jsi '%s'.\n", str);
return 0;
}
1) char * str máš už ukazatel a scanf chce adresu, proto ti to hlásí chybu
2) pokud to chceš použít takhle, musíš mít pamět alokovanou což ti u globální proměnné nepůjde, musel by si mít char str[30] třeba
3) pokud píšeš složitější program a neporadíš si s tímhle, tak bych začal psát jednodušší
-
Nenapadlo mě, že by scanf chtěl adresu... Díky. Teď už to vím a pro příště se poučím.
Pomohlo mi definovat proměnnou char str2[30], jejíž hodnotu jsem potom přiřadil globální proměnné char *str. Myslím si sice, že to není moc elegantní řešení (možná i trochu prasácké), ale prozatím funguje, přestože GCC hlásí varování.
Když jsem ten program začínal psát, měl jsem tam vstupní proměnnou pevně definovanou, protože jsem znal správný výstup. Zadávání vstupu uživatelem jsem přidal až jako poslední věc, a nenapadlo mě, že by s tím byl tak velký problém. Neměl jsem páru o tom, jak scanf funguje.
P.S. Možná máme jiný názor na to, co je "složitější" a "jednodušší" program.
Jsem v C relativní začátečník. Dřív jsem psal v C# (a to bylo ještě na Win), který je v těchto věcech jednodušší.
Znovu děkuji. Program je hotový.
-
4. globalni promenna je v C prasarna, udelej ji lokalni v main a predavej ji pomoci parametru funkce
-
Pomohlo mi definovat proměnnou char str2[30], jejíž hodnotu jsem potom přiřadil globální proměnné char *str. Myslím si sice, že to není moc elegantní řešení (možná i trochu prasácké), ale prozatím funguje, přestože GCC hlásí varování.
Proč je potřeba něčeho takovýho ???
-
4. globalni promenna je v C prasarna, udelej ji lokalni v main a predavej ji pomoci parametru funkce
To mě ani nenapadlo :o
Ale jak to mám udělat, pokud chci do té proměnné zapisovat z více funkcí?
Proč je potřeba něčeho takovýho ???
Nevím, jak to mám lépe udělat :(
-
Předně si ujasni používání pointerů. To je naprostej základ.
Dále: když už použiješ nějaké strx[y], tak proč už ne rovnou tu "primární" str? tedy třeba char str[256]. Vyhraď si raději více místa, protože pokud někdo zadá delší řetězec, než máš vyhrazenou paměť, je z toho průser.
Nicméně i přesto si ji raději deklaruj v těle main.
-
Předně si ujasni používání pointerů. To je naprostej základ.
Dále: když už použiješ nějaké strx[y], tak proč už ne rovnou tu "primární" str? tedy třeba char str[256]. Vyhraď si raději více místa, protože pokud někdo zadá delší řetězec, než máš vyhrazenou paměť, je z toho průser.
Nicméně i přesto si ji raději deklaruj v těle main.
Tak kde mám používat pointery? Pořád mi není jasné, k čemu jsou.
Globální *str vyměním za str[X].
Když někdo zadá delší řetězec, tak se prostě ta část, která přesahuje, neuloží, ne? Na konci bude pořád nullbajt.
Co si mám deklarovat v main()?
-
Globální *str vyměním za str[X].
Když někdo zadá delší řetězec, tak se prostě ta část, která přesahuje, neuloží, ne? Na konci bude pořád nullbajt.
opravdu si precti neco o C a idealne i o asembleru abys pochopil jak to funguje - kdyz do pole zapises vetsi pocet bytu, nez ma kapacitu, tak to pretece a bud si prepises dalsi globalni data, nebo budes zapisovat uz mimo pamet vyhrazenou pro tvuj program a kernel ti to zatrhne (SIGSEGV)
Tak kde mám používat pointery? Pořád mi není jasné, k čemu jsou.
ukazatel je adresa do pameti - kdyz tam je hvezdicka, pracujes s daty na te adrese, kdyz tam hvezdicka neni, pracujes s adresou samotnou - polopaticteji uz to rict asi nejde
-
ukazatel je adresa do pameti - kdyz tam je hvezdicka, pracujes s daty na te adrese, kdyz tam hvezdicka neni, pracujes s adresou samotnou - polopaticteji uz to rict asi nejde
To chápu. Ale kdy mám použít ukazatel a ne?
O C si určitě něco přečtu. Teď toho vím sice víc, ale také víc věcí nechápu a stále vím, že nic nevím.
-
Začít můžeš třeba tady: http://www.linuxsoft.cz/article_list.php?id_kategory=186.
Dokud nebudeš mít jasno v zápisech typu char, *char, char[], *char[], **char a podobně, budeš to mít těžké.
Něco podobného, s čím se tady trápíš, se řeší zde: http://www.linuxsoft.cz/article.php?id_article=578.
Čti a zkoušej si to pořád dokola, dokud to nepochopíš. Hodně štěstí.
-
Začít můžeš třeba tady: http://www.linuxsoft.cz/article_list.php?id_kategory=186.
Dokud nebudeš mít jasno v zápisech typu char, *char, char[], *char[], **char a podobně, budeš to mít těžké.
Něco podobného, s čím se tady trápíš, se řeší zde: http://www.linuxsoft.cz/article.php?id_article=578.
Čti a zkoušej si to pořád dokola, dokud to nepochopíš. Hodně štěstí.
No... Díky. Proberu se tím.