LINUX.ORG.RU

Давайте поиграем

 


0

1

Замечательный варгейм

Я застрял на 6ом таске. Никак не могу нормально передать строку на вход программе.

#include <stdio.h>
#include <string.h>

void prompt_name(char *name, char *msg){
        char buf[4096];

        puts(msg);
        read(0, buf, sizeof buf);
        *strchr(buf, '\n') = 0;
        strncpy(name, buf, 20);
}

void prompt_full_name(char *fullname) {
        char last[20];
        char first[20];

        prompt_name(first, "Please enter your first name: ");
        prompt_name(last, "Please enter your last name: ");

        strcpy(fullname, first);
        strcat(fullname, " ");
        strcat(fullname, last);
}

int main(int argc, char **argv){
        char fullname[42];

        prompt_full_name(fullname);
        printf("Welcome, %s\n", fullname);

        return 0;
}
Пыдаюсь передать в код 2 строки. В итоге ловлю сигфолт.
[actics@x120e ~]$ echo -ne "asdasdasdsd\ndfsdff\n" | ./c
Please enter your first name: 
Please enter your last name: 
Ошибка сегментирования (core dumped)
Возможно ли передать строки так, что бы сигфолта собственно не было?

И да, было бы очень классно, если бы кто-нибудь присоединился)


у тебя первый же вызов prompt_name вычитывает обе строки, соответственно при втором вызове ты пишешь 0 в произвольное место.

так должно работать:

void prompt_name(char *name, char *msg){
        puts(msg);
        scanf("%s",name);
}

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

мне её сломать нужно.

смотри - что куда пишется. И пиши что нужно и куда нужно.

drBatty ★★
()

Что кулхацкерские игрульки делают во взрослом Development? Уберите в толксы.

anonymous
()
$ perl -e 'print "1234\n"."\0"x(4096-5) for 1..2;' | ./c
Please enter your first name: 
Please enter your last name: 
Welcome, 1234 1234

Oops, опоздал.

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

Сканало и без файла!
perl -e 'print («t\n».(" «x4094).„123123k\n“)' | ./c
Почему такая магия, мне никак в голову не лезет? Он же должен четко считывать до перевода. или нет?

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

С терминала почему-то считывает до \n. Из файла/stdin честно считывает по 4096 байт, а потом устанавливает конец строки на \n.

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

Вот это-то и странно? Где можно почтитать про сспецифику работы с stdin?

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

Никакой магии. read читает столько, сколько может. При ручном вводе он может сразу прочесть только то, что до перевода, через пайп, может вообще все. Но так как мы ему говорим прочитать только 4096 символов, остаток он оставляет для следущего read.

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

проблема тольк ов том, что read не знает, откуда он читает. С stdin, из файла или вообще из сети. Я решил, что это просто специфика заботы драйвера stdin

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

read не знает, согласен. Но вот здесь - http://linux.die.net/man/3/stdin есть интересное примечание

Note that in case stdin is associated with a terminal, there may also be input buffering in the terminal driver, entirely unrelated to stdio buffering. (Indeed, normally terminal input is line buffered in the kernel.)

То есть по умолчанию при вводе из терминала включена построчная буферизация, и соответственно read доступна каждый раз всего одна строка. В случае же пайпов, read доступно все переданное содержимое, так как данные уже идут не через терминал.

keyran ★★
()

Господа, следующая проблема

$ ./c <<< ./p.py «0x01020304»
Please enter your first name: 
Please enter your last name: 
Segmentation fault
и
$ ./p.py «0x01020304» | ./c
Please enter your first name: 
Please enter your last name: 
Welcome, AAAAAAAAAAAAAAAAAAA 123
Почему так? p.py не изменялся

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

Потому что в случае <<< она получает на вход строку "./p.py «0x01020304»", а не результат выполнения этой команды.

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