Поглед напред в C/Reading

Написах този код, като един вид поглед напред.

int main() {
    char a[100];
    char b[100];
    scanf("%s", a);
    if (a[0] == '@') {
        scanf("{%s}", b);
    }
    printf("%s\n", b);
}

По някаква причина получавам segfault, след като натиснах enter за първи път, въведеното ми беше @hi. Какво става?


person tekknolagi    schedule 20.09.2011    source източник
comment
Грешката, която направихте тук, е същата като тази тук: (stackoverflow.com/questions/7466297/) - Вие презаписвате глобално съхранен низ, който е дълъг само 1 знак.   -  person Mysticial    schedule 20.09.2011
comment
Въздишка Кълна се, 50% от всички представители идват от тези въпроси.   -  person flight    schedule 20.09.2011
comment
Не разбирам съвсем какво не е наред в свързания въпрос... o.O   -  person tekknolagi    schedule 20.09.2011
comment
@quasiverse: Ето защо ще започна да ги оставям.   -  person Mysticial    schedule 20.09.2011
comment
Добре, току-що поправих това. Премахна заданието. Все още сегфаулти.   -  person tekknolagi    schedule 20.09.2011
comment
Грешката е следната char *a = "0"; Вие присвоявате глобално съхранен низ с дължина 2 в a. Когато го презапишете с scanf, пишете 4 знака (включително NULL).   -  person Mysticial    schedule 20.09.2011
comment
@Mysticial Премахнах заданието   -  person tekknolagi    schedule 20.09.2011
comment
Опитайте това: char a[100]; и char b[100];.   -  person Mysticial    schedule 20.09.2011
comment
@tekknolagi Сега създавате символен указател, който не сочи никъде. Това е още по-лошо.   -  person flight    schedule 20.09.2011


Отговори (2)


Проблемът в първото ви парче код (преди редакцията) беше, че създавате низ, съхраняващ 2 знака. „0“ и NULL. След това се опитвате да презапишете това с 4 знака от scanf.

Във втората част от кода вие не насочвате показалеца на char никъде. Току-що го декларирахте, без да му давате стойност, така че може да сочи към нещо.

За да получите поведението, което искате, трябва да създадете масив от знаци като този:

char a[100];
char b[100];

Ще трябва да направите масива достатъчно голям за вашите цели.

Освен това, ако искате да прочетете двата низа, ще трябва да "консумирате" бялото пространство между тях. За да направите това, променете второто scanf на:

scanf(" {%s}", b);

Обърнете внимание на интервала преди {.

person flight    schedule 20.09.2011
comment
Направих това и сега, когато i scanf, резултатът за b е пълна глупост. - person tekknolagi; 20.09.2011
comment
@tekknolagi Какво въведохте? - person flight; 20.09.2011
comment
@tekknolagi Вместо scanf("{%s}", ...) опитайте scanf(" {%s}", ...). Обърнете внимание на пространството. - person flight; 20.09.2011
comment
а, вярно. как мога да го накарам да прескочи цялото празно пространство? - person tekknolagi; 20.09.2011
comment
@tekknolagi Какво имаш предвид? Това пропуска цялото празно пространство. - person flight; 20.09.2011
comment
Ами ако имам табулатори и нови редове, които ги разделят...? - person tekknolagi; 20.09.2011
comment
Защо пространството прави всичко различно? И защо, ако въведа @hi {lol}, се отпечатва lol}? - person tekknolagi; 20.09.2011
comment
@tekknolagi Интервалът представлява всеки празен знак и наистина получавате lol} е това във вашия scanf. Той вижда {, така че го игнорира във входа и след това получава низ. След това вижда }, но това вече е взето като част от низа, така че нищо не се случва. - person flight; 20.09.2011
comment
Как да вкарам няколко думи в низ? като ако искам да имам { sentence0 ; sentence1 ; sentence2 }...по някаква причина вижда само първата дума - person tekknolagi; 20.09.2011
comment
@tekknolagi Низовете са разделени с интервали. Наистина не мога да продължа да чета тези коментари. Ако искате допълнителна помощ, винаги можете да зададете нов въпрос или да го потърсите. - person flight; 20.09.2011

scanf("%s", a);, според man страница, се опитва да съхрани низ (%s) в посочените местоположения до по аргументите на указателя, които следват формат (a). В този случай a е неинициализирано и не сочи към никакво място за съхранение. За да прочетете един знак, разгледайте този пример:

int main(int argc, char **argv)
{
    char c;


    /* among other things, read a character */
    scanf("%c", &c);

    return 0;
}

разширете го, за да получите желаното поведение. Освен това бих ви посъветвал да избягвате scanf и да правите сами съвпадението, докато четете с fgets.

person Michael Foukarakis    schedule 20.09.2011