LINUX.ORG.RU

Только начинаю изучать Язык Си...

 ,


1

2

В общем начал изучать C по книге K&R. В общем задача вывести символы ввода в выходной поток. Для себя немного модифицировал задачу, чтобы при выводе символы проверялись на == ';', и если условие совпадает, то сделать перевод строки. В общем то работает, но блин на выходе вместо содержимого файла пишет кучу цифр. Вот код:

#include <stdio.h>

main ()
{
    int c;

    while ((c = getchar()) != EOF)
	if (c == ';')
            printf ("%d\n", c);
        else
	    printf ("%d", c);
}

printf («%d\n», c);

%d
пишет кучу цифр

Как и положено.

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

Нет, ну действительно man 3 printf.

%d - вывод целого, int, скорее всего у тебя 4 байта. Тебе нужно вывести символ. В int c ты считываешь один символ(1 байт), который автоматически в C преобразуется в int. Далее ты и выводишь его как int, отсюда числа. Чтобы вывести его как символ, нужен спецификатор %c.

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

есть риск, что 1 байта не хватит для представления EOF

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

И вместо int c лучше char c

А тебя не смущает, что getchar возвращает int вместо char?

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

И вместо int c лучше char c

Таки да, хуже. Ибо легальный символ идет как unsigned char, а EOF как -1. man 3 getchar и не учи плохому.

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

И вместо int c лучше char c

Вот не нужно вредных советов. getchar возвращает int, поэтому нужно int. Только после проверки на EOF его можно скастовать в char.

slovazap ★★★★★
()

int
main(){
	typedef long int __ssize_t;
	typedef __ssize_t ssize_t;
	ssize_t write(int,const void *,ssize_t);
	int getchar(void);

	int c;
	while((-1)!=(c=getchar())){
		write(1,&c,1);
		if(c!=';')continue;
		write(1,"\n",1);
        }
        return 0;
}


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

Ну тогда уж и read вместо getchar. Но зачем? Не переносимо же, только POSIX.

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

А зачем ему сразу write?

Только сисколы, только хардкор?!

Twissel ★★★★★
()

Если у Вас русская версия K&R, то описание prtinf Вы можете найти в 7-й главе, второго раздела на странице 165, а на следующей странице (166) — описание основных параметров, принимаемых функцией и способы вывода. А вообще, Вы в неправильном месте задаете вопросы, т.к. здесь в, основном, приходят повы<censored>ёбываться потешить своё ЧСВ. Лучше зайдите на irc.freenode.net #c, там адекватные чуваки, которые объяснят доступно.

zl0y
()
>> cat 1.c
#include <stdio.h>
int main (){
  int c;
  while((c = getchar()) != EOF){
    if (c == ';')
      printf ("%c\n", c);
    else
      printf ("%c", c);
  }
  return 0;
}

>> gcc 1.c -o test

>> ./test 
Превед, чувак! Тест; тест; тест!
Превед, чувак! Тест;
 тест;
 тест!

Кстати, мне интересно, как это будет в хрюникоде работать?

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

если выбирать С как первый язык программирования (что очень очень плохо) то всёж лучше издание первое(т.е 1978-9 анг.изд и 1985 русское) где бюрократии поменьше.

если же С не первый язык программирование и идёт именно изучение синтаксиса очередного императивного с его(с) индивидуальными особенностями - то следует отметить что С появился в среде где был популярен подход к созданию специализированных языков - чем и является форматирующие строки принтф(спринф(формат)).

а вообще лови ТС(хоть и непофеншую и ужасу вараргов - но так оно первые года работало):

http://minnie.tuhs.org/cgi-bin/utree.pl?file=V2/lib/printf.c

printn(n,b) {
	extern putchar;
	auto a;

	if(a=n/b) /* assignment, not test for equality */
		printn(a, b); /* recursive */
	putchar(n%b + '0');
}

printf(fmt,x1,x2,x3,x4,x5,x6,x7,x8,x9)
	char fmt[];
	{
	extern printn, putchar;
	char s[];
	auto adx[], x, c;

	adx = &x1; /* argument pointer */
loop:
	while((c = *fmt++) != '%') {
		if(c == '\0')
			return;
		putchar(c);
	}
	x = *adx++;
	switch (c = *fmt++) {

	case 'd': /* decimal */
	case 'o': /* octal */
		if(x < 0) {
			x = -x;
			if(x<0) {  	/* is - infinity */
				if(c=='o')
					printf("100000");
				else
					printf("-32768");
				goto loop;
			}
			putchar('-');
		}
		printn(x, c=='o'?8:10);
		goto loop;

	case 'c': /* char */
		putchar(x);
		goto loop;

	case 's': /* string */
		s = x;
		while(c = *s++)
			putchar(c);
		goto loop;
	}
	putchar('%');
	fmt--;
	adx--;
	goto loop;
}

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

А ты, на секундочку, только что в чем тестировал? Не в КОИ8 же? Вот в UTF-8 работать будет замечательно, для того и придуман.

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

(что очень очень плохо)

потому что?

Вообще, я бы рекомендовал изучать С в связке с ассеблером (дизассемблировать листинги/упраженения и смотреть в GDB под «капот»). Таким образом образуется лучшее понимание того, что происходит и почему. Поинтеры/битовые операции и т.д. при таком подходе вообще оседают в голове на ура. Бзв, вот хорошая книжечка по ассемблеру для начала

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

С как первый язык программирования (что очень очень плохо)

Ну если писать так, как ты, то даже больше — вообще не стоит браться за программирование (потому что ой как плохо всё).

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

Тоже не вижу в C ничего плохого. Возможность отстрела на ног на этапе обучения считаю полезной. Но на ассемблере бы настаивать не стал, имхо, достаточно «обзорного урока»: как «выглядит» память, что такое регистр, десяток команд, организация ветвления, цикла, стека.

JaneDoe
()

Скажу как человек, который прошел этап изучения синтаксиса языка. Книга K&R должна быть 2 или 3й по счету, никак не первой. Могу предложить начать с Гриффитсов (2013), С.Кочан (2007), возможно и МакГрат (2016).

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

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

Естественно, в КОИ8Р, других не имеем!

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

Книга K&R должна быть 2 или 3й по счету
Это не потому что не осилил, а потому что книга предназначена была на уже специалистов в программировании того времени.

Ну, не знаю. Как по мне, то браться за k&r нужно сразу. Там всё расжевано: те же циклы, ветвления, функции с рекурсией, базовые алгоритмы в виде разных сортировок и обход бинарного дерева. Другими словами дана та база, после которой смотришь на любой другой язык без мыслей «Ох них<censored>уя себе». Да, никто не говорит, что будет легко, но от этого появляется некий фан. Кстати, после этого можно взглянуть, например, вот на этот курс

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

потому что Си - буквально мобильный структурный(фигурные скобки вот это вот всё) ассемблер.

тем и отличается от «обычных» ассемблеров которые устаканились на лет 15 раньше как стопка операторов меняющих состояние машины.

и как ассемблер просто игнорирует типоразличность.

вообще только после сырцов Лиона догнал(т.е сконструировалась непротиворечивая модель генезиса) отчего в сишке есть ->

да вообще см первую страницу сырцов Лионовых(http://wiki.tuhs.org/doku.php?id=publications:books) сырцов:

unix/param.h Page 2
0170 /* structures to access integers : */
0171
0172
0173     /* single integer */
0174
0175 struct {    int   integ;   };
0176
0177
0178     /* in bytes  */
0179
0180 struct {    char lobyte;  char hibyte; };
0181
0182
0183     /* as a sequence */
0184
0185 struct {     int  r[];     };

а дальше к любому числу(указателю)адресу p

p->integ

p->r[index]

и для любых списочных структур можно

startindex[p][p][p]....[p] 
любой степени косвенности

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

Как по мне, то браться за k&r нужно сразу. Там всё расжевано

Ты вопрос человека читал? :) Я начинал с определенным бэкграундом, знанием про маны и т.п. В книге дофига опечаток, которые поймешь лишь _после_ изучения синтаксиса, а также прочтешь про пре-процессор. Т.е. книга отличная, замечательная, и даже сойдет для первого раза ЕСЛИ пропускаешь примеры: не запустилось? проехали и т.д. ТОГДА будет клево, да.

Я получил максимальное удовольствие от K&R уже зная основы языка, зная синтаксис, зная что и как. Книга хорошая, не спорю.

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

а затем прст

unix/seg.h
0304 #define UISD 0177600 /*first user I-space descriptor 
0305                                          register */


unix/main.c

1561    UISD->r[0] = 077406;

такие дела.
qulinxao ★★☆
()
Ответ на: комментарий от anonymous

Хороший вопрос! Сейчас проверю в своем utf8 терминале!

λ> gcc test.c
λ> ./a.out
че там с кодировками?
че там с кодировками?
Эдик, возвращайся в свой однобайтовый мирок.

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

И книги, что я рекомендовал никак не претендуют на замену K&R (у авторов даже цели не было). Отличие от K&R (максимально объективно):

  • В Гриффитсе нету в коде ни одной опечатки (!); есть другие опечатки, но не в примерах
  • Кочан хоть и описал с субъективщиной (имхо), расписал очень-очень подробно

Да и вообще, мое мнение это подтверждение, того, что написано тут: http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-lis...

anonymous
()

Потому что ты указываешь в формате, что c должно быть отображено как число («%d», и да - man printf). Соответственно - отображается числовое значение символа. А надо юзать «%c»

alex4321
()
Ответ на: комментарий от anonymous
λ desktop /tmp → xclip -o > ccat.c
λ desktop /tmp → cat ccat.c
#include <stdio.h>
int main (){
  int c;
  while((c = getchar()) != EOF){
    if (c == ';')
      printf ("%c\n", c);
    else
      printf ("%c", c);
  }
  return 0;
}
λ desktop /tmp → make ccat
cc     ccat.c   -o ccat
λ desktop /tmp → ./ccat
Превед, чувак! Тест; тест; тест!
Превед, чувак! Тест;
 тест;
 тест!
λ desktop /tmp → echo $LC_ALL
ru_RU.UTF-8
theNamelessOne ★★★★★
()
Ответ на: комментарий от anonymous

Ты вопрос человека читал? :)

Я же ему ответил, следовательно читал.

Я начинал с определенным бэкграундом

Какой Вы молодец.

знанием про маны и т.п

никак не относится к бэкграунду, но да ладно...

В книге дофига опечаток, которые поймешь лишь _после_ изучения синтаксиса

Встречал пару опечаток только. Но опять же, никто не говорит, что нужно ограничиваться только одной книгой, хотя там всё описано и printf тому пример. Плюс, если человек пользуется линуксом, то он автоматически должен знать про man.

ЕСЛИ пропускаешь примеры: не запустилось? проехали

т.е. разбираться почему не запустилось и как запустить не нужно? Это путь какого-то дебила-пхпешника-неудачника.

уже зная основы языка, зная синтаксис, зная что и как.

Ведь Вы же узнавали основы, синтаксиси, что и как из этой книги?

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

В Гриффитсе нету в коде ни одной опечатки (!); есть другие опечатки, но не в примерах

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

что написано тут: http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-lis...

О! Спасибо за ссылочку.

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

Плюс, если человек пользуется линуксом, то он автоматически должен знать про man.

Не должен. Маны ОС-специфичны, POSIX-маны не во всех дистрах. Этими знаниями нельзя ограничиваться.

т.е. разбираться почему не запустилось и как запустить не нужно? Это путь какого-то дебила-пхпешника-неудачника.

Вот он и разбирается через форум. Вопрос только в том, что отличает ЛОР от пхп-форума :)

Ведь Вы же узнавали основы, синтаксиси, что и как из этой книги?

Нет. После того как я несколько раз замучился выпрашивать ответы в Интернет, я взял Гриффитса (вообще влет), после Кочан, после K&R, сейчас вот Стивенс и легендарное окружение Unix. И на подходе весь эпик: Седжвик, Прата, Кнут и дальше по списку =]

Так вот. После понимания основ синтаксиса (от и до) в сишке все становится просто. Увы, любой учебник среднего уровня слишком тянет с примерами, описаниями и иногда даже дают примеры со структурами из следующих глав: очень было «прикольно» читать якобы эффективный код не зная еще про объединения (нихрена не понял, ни строчки не запомнил, а всё, через 200 страниц книги конец и «поезд прошел»).

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

Не должен.

Мы сейчас не говорим про пользователей убунты.

Маны ОС-специфичны, POSIX-маны не во всех дистрах.

Серьёзно? Расскажите.

Этими знаниями нельзя ограничиваться.

Ни в коем случае, про ограничения не было и речи.

Вот он и разбирается через форум.

К сожалению, это беда современности. Мало кто сидит и разбирает проблему самостоятельно ☹

Нет. После того как я несколько раз замучился выпрашивать ответы в Интернет, я взял Гриффитса (вообще влет), после Кочан, после K&R, сейчас вот Стивенс и легендарное окружение Unix.

Я понял, Вы стартовали за долго до старта ☺

Так вот. После понимания основ синтаксиса (от и до) в сишке все становится просто.

Простите, а что сложного в Сишном синтаксисе?

zl0y
()
Последнее исправление: zl0y (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.