LINUX.ORG.RU

Учебный исходник Си вываливается с Segmentation fault.


0

0
#include<stdio.h>
int main(void)
{
        char ch;
        puts("Press any key");
        ch=getchar();
        printf("Key=%s",ch);


return(0);
}

При компиляции выводится сообщение:

test.c: In function ‘main’:

test.c:7: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘int’

Программа успешно запускается, но вываливается с Segmentation fault после ввода любого символа.

#include<stdio.h>
int main(void)
{
  char ch,ch2=0;
  puts("Press any key");
  ch=getchar();
  printf("Key=%s",ch);
  return(0);
}
anonymous ()
Ответ на: комментарий от aaz893
#include <stdio.h>
int main(void)
{
    char string[50];
    printf("Input string: ");
    scanf("%s", string);
    printf("String = %s\n",string);

    return(0);
}
Deleted ()
Последнее исправление: Deleted (всего исправлений: 1)

Мне все-таки интересно узнать одну вещь: Почему мой исходник не может работать при установленном %s ??

aaz893 ()
Ответ на: комментарий от aaz893

Потому что у тебя не строка, а символ, а printf ожидает строку с нулевым терминатором, которую не получает.

UVV ★★★★★ ()
Ответ на: комментарий от aaz893

Потому как %s ожидает УКАЗАТЕЛЯ, а не значение символа!

io ★★ ()
Ответ на: комментарий от UVV

Ясно. Но этот %s не моя отсебячина, так было написано в моем учебнике Си. И по всей видимости этот пример должен работать. Пусть даже это не совсем корректно.

У меня одного неправильно работает первоначальная версия исходника?

aaz893 ()
Ответ на: комментарий от aaz893

Но этот %s не моя отсебячина, так было написано в моем учебнике Си.

Выкинь этот учебник. Это серьезно, прямо сейчас. Возьми Кернигана и Ричи «Язык программирования Си».

И по всей видимости этот пример должен работать.

Нет, не должен.

Пусть даже это не совсем корректно.

Это не «не совсем корректно», а «не корректно».

Deleted ()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от aaz893

Как уже посоветовали, выкинь учебник. Изначальный код работать не будет.

UVV ★★★★★ ()
Ответ на: комментарий от aaz893

тебе уже наверное раз 100 сказали: читай K&R.

Deleted ()
Ответ на: комментарий от Deleted

«уже наверное раз 100 сказали: читай K&R.» А мне процитировать Ozon.ru, на котором говорится, что это не лучший выбор для новичков?

aaz893 ()
Ответ на: комментарий от aaz893

Тебе уже 100 раз говорили: почитай сначала K&R, а это говно, что читаешь, выкинь.

Eddy_Em ☆☆☆☆☆ ()

И прочитай уже man 3 printf, если в лом K&R открыть!

И вообще, на каждую используемую функцию man прочти, если не знаешь, что она делает.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от UVV

«Как уже посоветовали, выкинь учебник. Изначальный код работать не будет.» Черт, ну что же это за напасть? Это уже четвертый, если даже не пятый учебник. Такое впечатление, что все нормальные учебники куда-то спрятались.

aaz893 ()
Ответ на: комментарий от aaz893

ты можешь цитировать что угодно, в том числе ущербные учебники. Но это кому-то надоест и тебя забанят. K&R - это классика,и читать придется все равно.

Deleted ()
Ответ на: комментарий от aaz893

«уже наверное раз 100 сказали: читай K&R.» А мне процитировать Ozon.ru, на котором говорится, что это не лучший выбор для новичков?

Тогда продолжайте жрать кактус, он ведь для новичков.
Я только не пойму, какого хрена вы просите тут помощи?

andreyu ★★★★★ ()
Ответ на: комментарий от Eddy_Em

«И прочитай уже man 3 printf, если в лом K&R открыть!» Bash пишет: No manual entry for printf in section 3 See 'man 7 undocumented' for help when manual pages are not available.

aaz893 ()
Ответ на: комментарий от andreyu

«Я только не пойму, какого хрена вы просите тут помощи?» А что?

aaz893 ()
Ответ на: комментарий от aaz893

PRINTF(3)                                                            Linux Programmer's Manual                                                           PRINTF(3)

NAME
       printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf - formatted output conversion

SYNOPSIS
       #include <stdio.h>

       int printf(const char *format, ...);
       int fprintf(FILE *stream, const char *format, ...);
       int sprintf(char *str, const char *format, ...);
       int snprintf(char *str, size_t size, const char *format, ...);

       #include <stdarg.h>

       int vprintf(const char *format, va_list ap);
       int vfprintf(FILE *stream, const char *format, va_list ap);
       int vsprintf(char *str, const char *format, va_list ap);
       int vsnprintf(char *str, size_t size, const char *format, va_list ap);

   Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

       snprintf(), vsnprintf():
           _BSD_SOURCE || _XOPEN_SOURCE >= 500 || _ISOC99_SOURCE || _POSIX_C_SOURCE >= 200112L;
           or cc -std=c99

…
pacman -Qo /usr/share/man/man3/printf.3.gz
/usr/share/man/man3/printf.3.gz принадлежит man-pages 3.44-1


Что у тебя за дистрибутив такой идиотский?

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от aaz893

Потому что %s - это строка, а не символ. Строки в Си завершаются нулевым терминатором. При поиске этого нулевого терминатора твоя программа, видимо, залазит в чужую область памяти, об этом ей посылается сигнал и обработчик сигнала по умолчанию завершает твою программу.

К тому же при %s введенный параметр сам по себе интерпретируется как указатель, который может уже указывать не туда, куда надо.

hibou ★★★★★ ()
Ответ на: комментарий от Deleted

«K&R - это классика,и читать придется все равно.» Всему свое время. И это будет, но попозже.

aaz893 ()
Ответ на: комментарий от Eddy_Em

«Что у тебя за дистрибутив такой идиотский?» Crunchbang Linux

aaz893 ()
Ответ на: комментарий от hibou

Если бы ТС компилял как надо, с -Wall -Werror, то он просто не смог бы этот бред скомпилять:

gcc aaa.c -Wall -Werror
aaa.c: В функции <<main>>:
aaa.c:7:9: ошибка: format <<%s>> expects argument of type <<char *>>, but argument 2 has type <<int>> [-Werror=format]
cc1: all warnings being treated as errors

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от hibou

hibou, благодаря за объяснение!

Мда, поиск нормального учебника оказался гораздо более сложной задачей, чем мне казалось ...

aaz893 ()
Ответ на: комментарий от Eddy_Em
./1.c:7:22: warning: format specifies type 'char *' but the argument has type 'char' [-Wformat]
        printf("Key=%s",ch);
                    ~^  ~~

clang таки выдает чуть более точные предупреждения (char/int)

wota ★★ ()
Последнее исправление: wota (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

Спасибо, учту на будущее. Я просто не ожидал, что при warnings программа может вылетать/

aaz893 ()
Ответ на: комментарий от aaz893

Вот лучше вообще приручить себя всегда при компиляции писать -Wall -Werror, а еще лучше — сделать псевдоним:

alias gcc="gcc -Wall -Werror"

если уж не хочешь обращать внимания на предупреждения.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Deleted

«Тогда жри кактус.» Боюсь, что на моем текущем уровне K&R 4 тоже будет кактусом.

aaz893 ()

%s - вывод строки %c - вывод символа Строка должна заканчиваться нулевым символом. Ты же под видом строки пытаешься вывести символ. Вот printf и пытается вывести всё что лежит начиная с адреса в ch пока не встретит нулевой символ. И, естественно, адрес, который лежит в ch, находится за пределами сегмента памяти, выделеного твоей программе.

gear ★★★ ()
Ответ на: комментарий от aaz893

Если уж очень хочешь сделать так как ты, то вот так должно работать:

#include<stdio.h>
int main(void)
{
        char ch[2];
        puts("Press any key");
        ch[0]=getchar();
        ch[1] = '\0';
        printf("Key=%s",ch);
        return(0);
}

Должно работать. Компилятора под рукой щас нет, чтоб проверить ))

hibou ★★★★★ ()
Последнее исправление: hibou (всего исправлений: 2)
Ответ на: комментарий от Eddy_Em

Eddy_Em, на всякий случай, дабы быть уверенным, что мы имеем в виду одну и туже книгу, вот ссылка на K&R 4 http://www.iu.hio.no/~mark/CTutorial/CTutorial.html

Именно эту версию я и имел в виду. Насколько я понял, эту версию писал уже другой человек, а не непосредственно сами K&R. Просто старое название сохранилось.

aaz893 ()
Ответ на: комментарий от hibou

hibou, действительно работает! Но учебник все-таки поменяю.

aaz893 ()
Ответ на: комментарий от aaz893

Обрати внимание, ch в данном случае является адресом, а не содержанием. :)

hibou ★★★★★ ()
Ответ на: комментарий от aaz893

Но этот %s не моя отсебячина, так было написано в моем учебнике Си.

Можешь им (учебником) подтереться.

Manhunt ★★★★★ ()
Ответ на: комментарий от aaz893

Перестань вестись на учебники типа «С за 7 дней» - ты в них ничего толкового не найдешь. Читай литературу, написаную создателями языка, - лучше них тебе никто о языке не расскажет. Тебе уже много кто посоветовал Кернигана и Ричи - очень правильно посоветовали.

gear ★★★ ()
Ответ на: комментарий от hibou

«Обрати внимание, ch в данном случае является адресом, а не содержанием.» Ты имеешь в виду массивом? Ну да. Хотя вообще-то, это небольшое читерство с твоей стороны ;) Ведь это фактически строка. Насколько мне известно, в Си нет специальной строковой переменной. Строка сохраняется просто как массив символов.

aaz893 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.