Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Нужно разобрать строку из чисел на отдельные числа

1.8K
23 августа 2006 года
Andreww
81 / / 02.01.2004
Всем привет! Задача у меня в следующем -- в текстовом файле записаны в два столбика числа, группы чисел разделены пустой строкой, вот например:

20 23
20 22
21 22
21 21

20 63
21 62
23 62

20 106
21 105
22 105
23 105
24 105

Нужно считать первую группу, обработать, потом вторую, и так до конца файла. Думаю сделать два вложенных цикла -- внешний do {} while (!EOF) чтобы идти по всему файлу, и внутренний -- чтобы считывать группу чисел до пустой строки.
Вопрос -- как сделать цикл который бы считывал пары чисел в группах? Была идея считывать построчно, пока не наткнемся на пустую строку, но как тогда из строки вытащить первое и второе число?
Страницы:
3.0K
23 августа 2006 года
Мerlin
267 / / 25.07.2006
[QUOTE=Andreww]...<skipped>...Вопрос -- как сделать цикл который бы считывал пары чисел в группах? Была идея считывать построчно, пока не наткнемся на пустую строку, но как тогда из строки вытащить первое и второе число?[/QUOTE]Допустим строка считана в переменную char str []. Тогда
 
Код:
char *lc = strtok(str, " ");
  while(lc!=NULL)
  {
    // Текущее число
    int i = atoi(lc);
    lc = strtok(NULL, " ");
  }
3
23 августа 2006 года
Green
4.8K / / 20.01.2000
А что значит считать и что значит обработать?
Как отражается разбиение по группам на обработке?
1.8K
28 августа 2006 года
Andreww
81 / / 02.01.2004
Green,
попробую обьяснить проще. вот если бы было просто два столбика чисел без разделения на группы:

20 23
20 22
21 22
21 21
20 63
21 62
23 62
20 106
21 105
22 105
23 105
24 105

то можно было бы просто считывать все подряд с помощью fscanf до самого конца файла. А так группы разделены пустыми строками, нужно считать группу (первая колонка допустим X, вторая Y) и сделать какие-то действия с числами этой группы. И только потом перейти к следующей группе. Может я плохо обьясняю?
1.8K
28 августа 2006 года
Andreww
81 / / 02.01.2004
Merlin,
а что делает функция strtok?
16K
29 августа 2006 года
aragaer
25 / / 28.07.2006
strtok(строка, строка2)
Ищет в первой строке первое вхождение символов из второй и заменяет их на \0. Возвращает указатель на начало строки и запоминает место, на котором остановилась. Теперь можно вызывать strtok(null, строка2). Таким макаром вся строка разбивается на лексемы.
240
29 августа 2006 года
aks
2.5K / / 14.07.2006
strtok не совсем безопасная функция из за своих глобальных данных. Особенно когда она может вызваться паралельно. Лучше использовать Другие функции разбора по разделителям из string.h или еще лучше токенайзер из буста:
boost::tokenizer
252
29 августа 2006 года
koderAlex
1.4K / / 07.09.2005
Форматированный ввод ещё никому не мешал ).
1.8K
29 августа 2006 года
Andreww
81 / / 02.01.2004
koderAlex, можно подробнее?

Merlin, что-то приведенная конструкция считывает только первое число и останавливается. или я туплю...
252
29 августа 2006 года
koderAlex
1.4K / / 07.09.2005
fscanf(FILE,"%d %d",mas,mas[i+1]);
пример форматированного ввода - скушает из файла строку "12 13\n" и зделает mas=12;mas[i+1]=13.
1.8K
29 августа 2006 года
Andreww
81 / / 02.01.2004
koderAlex,
это конечно хорошо, но нужно паралельно отслеживать не закончилась ли группа... чтобы не залезть в следующую.
3
29 августа 2006 года
Green
4.8K / / 20.01.2000
Ну а в чем у тебя проблема?
Алгоритм, ты уже описал, формализуем его:
1) пока не достигнем конца файла считываем строку;
2) проверяем, что она не пустая
2.1) если не пустая - парсим,
2.2) если пустая - обрабатываем ранее полученные значения;
3) повторяем с п.1
3
29 августа 2006 года
Green
4.8K / / 20.01.2000
Если пишешь на С++, fscanf лучше не использовать, т.к. это C-style.

Я бы решил эту задачу как-то так в общем виде:
Код:
bool isWhitespace(const string& str)
{
    return (str.find_first_not_of(" \t\v\r\n") == string::npos);
}



ifstream in(filename);
while( !in.eof() ) {
    string str;
    getline(in, str);
    if( isWhitespace(str) ) {
        //
        // process data
        //
    } else {
        istringstream is(str);
        int x, y;
        is >> x >> y;
        // store x, y
    }
}

Ну конечно полученные x, y надо сохранять в некотором хранилище, чтоб потом обработать полученные данные в секции "process data".
1.8K
30 августа 2006 года
Andreww
81 / / 02.01.2004
Green,
та я как-то по привычке в стиле С :-) а в каком заголовочном файле находится "ifstream"?
3
30 августа 2006 года
Green
4.8K / / 20.01.2000
#include <fstream>
1.8K
30 августа 2006 года
Andreww
81 / / 02.01.2004
Green,
спасибо, что-то тупею я....
3.0K
31 августа 2006 года
Мerlin
267 / / 25.07.2006
[QUOTE=Andreww]koderAlex, можно подробнее?

Merlin, что-то приведенная конструкция считывает только первое число и останавливается. или я туплю...[/QUOTE]
Код:
FILE *stream;
  char line[100];
 
  if((stream = fopen("C:\\t.txt", "r"))!=NULL)
  {
    while(fgets(line, 100, stream)!=NULL)
    {
      char *lc = strtok(line, " ");
      int x = atoi(lc);
      lc = strtok(NULL, " ");
      if(lc==NULL)
      {
        // конец группы
        // ...
      }
      else
      {
        int y = atoi(lc);
        // считанны два числа в переменные x и y
        // ...
      }
    }
    fclose(stream);
  }
3
31 августа 2006 года
Green
4.8K / / 20.01.2000
А зачем такие сложные конструкции?
 
Код:
if((stream = fopen("C:\\t.txt", "r"))!=NULL)
3.0K
31 августа 2006 года
Мerlin
267 / / 25.07.2006
[QUOTE=Green]А зачем такие сложные конструкции?
 
Код:
if((stream = fopen("C:\\t.txt", "r"))!=NULL)
[/QUOTE]
Вообще-то я проверил код и не заметил, чтоб компилятор жаловался, что нафига так сложно...

А на твой код:

error C2079: 'in' uses undefined class 'basic_ifstream<char,struct std::char_traits<char> >'

error C2440: 'initializing' : cannot convert from 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' to 'int'

error C2228: left of '.eof' must have class/struct/union type

А это вообще красота:

fatal error C1903: unable to recover from previous error(s); stopping compilation
3
31 августа 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=Мerlin]Вообще-то я проверил код и не заметил, чтоб компилятор жаловался, что нафига так сложно...
[/QUOTE]
Вообще-то код на языках программирования пишется для людей, а не для компиляторов или машин.
Чего же ты не написал тогда так:
 
Код:
FILE *stream; char line[100]; char *lc;
if((stream = fopen("C:\\t.txt", "r"))!=NULL) { while(fgets(line, 100, stream)!=NULL) {
   int x = atoi( strtok(line, " ") ); if((lc = strtok(NULL, " "))==NULL) { /* конец группы */
   } else { int y = atoi(lc); /* считанны два числа в переменные x и y */  } }
  fclose(stream); }

компилятор тоже ругаться не будет

Скажи, почему бы вместо
 
Код:
if((stream = fopen("C:\\t.txt", "r"))!=NULL)

не написать "по-человечески":
 
Код:
stream = fopen("C:\\t.txt", "r");
if(stream != NULL)


[QUOTE=Мerlin]
А на твой код:

error C2079: 'in' uses undefined class 'basic_ifstream<char,struct std::char_traits<char> >'

error C2440: 'initializing' : cannot convert from 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' to 'int'

error C2228: left of '.eof' must have class/struct/union type

А это вообще красота:

fatal error C1903: unable to recover from previous error(s); stopping compilation[/QUOTE]
А не пробовал нужные заголовочные файлы подключать? Очень полезная вещь.
3.0K
31 августа 2006 года
Мerlin
267 / / 25.07.2006
[QUOTE=Green]Вообще-то код на языках программирования пишется для людей, а не для компиляторов или машин.
Чего же ты не написал тогда так: <skipped>
компилятор тоже ругаться не будет[/QUOTE]Понял. Ты имел ввиду фигурную скобку после if. Как говорят о вкусах не спорят. imho, так лучше видно, что делается, если файл успешно открыт. Да и в реальной программе нужен был бы и else блок(или что-то подобное).
Цитата:
А не пробовал нужные заголовочные файлы подключать? Очень полезная вещь.

Ты как всегда прав. Подключил <fstream>, и сразу другая картина:

error C2664: '__thiscall std::basic_ifstream<char,struct std::char_traits<char> >::std::basic_ifstream<char,struct std::char_traits<char> >(const char *,int)' : cannot convert parameter 1 from 'class std::basic_string
<char,struct std::char_traits<char>,class std::allocator<char> >' to 'const char *'

No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

error C2079: 'is' uses undefined class 'basic_istringstream<char,struct std::char_traits<char>,class std::allocator<char> >'

error C2440: 'initializing' : cannot convert from 'class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' to 'int'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
warning C4552: '>>' : operator has no effect; expected operator with side-effect

Но по правде говоря, пред.версия из-за

fatal error C1903: unable to recover from previous error(s); stopping compilation

мне лучше нравилась. :)

3
31 августа 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=Мerlin]Понял. Ты имел ввиду фигурную скобку после if. Как говорят о вкусах не спорят. imho, так лучше видно, что делается, если файл успешно открыт. Да и в реальной программе нужен был бы и else блок(или что-то подобное).
[/QUOTE]
Нет, я имел в виду не фигурную скобку, а то, что понятнее разносить сложные конструкции на несколько простых:
[QUOTE=Green]
Скажи, почему бы вместо
 
Код:
if((stream = fopen("C:\\t.txt", "r"))!=NULL)

не написать "по-человечески":
 
Код:
stream = fopen("C:\\t.txt", "r");
if(stream != NULL)

[/QUOTE]
Неужели, это трудно для понимания?

[QUOTE=Мerlin]Ты как всегда прав. Подключил <fstream>, и сразу другая картина:
<skip>
[/QUOTE]
Извини, но не стоит так демонстративно показывать свою некомпетентность.
Очень плохо, что ты не умеешь читать сообщения об ошибках.
Даже не видя твоего кода, можно сказать, что ты определил filename, как тип string, хотя надо было бы как const char*.
Ну да ладно, кто тебе мешает сделать так: filename.c_str()

и ещё раз повторюсь (что то я часто повторяюсь, это настораживает):
А не пробовал ВСЕ нужные заголовочные файлы подключать? Очень полезная вещь.
3.3K
31 августа 2006 года
ShadyMan
191 / / 15.07.2006
[QUOTE=Green]
Скажи, почему бы вместо
 
Код:
if((stream = fopen("C:\\t.txt", "r"))!=NULL)

не написать "по-человечески":
 
Код:
stream = fopen("C:\\t.txt", "r");
if(stream != NULL)

[/QUOTE]
Вообще-то это гораздо изящнее можно представить в таком виде:
if (stream=fopen("c:\\t.txt", "r"))

А интересно, зачем вообще в языке С допускаются сокращённые конструкции (например, *p1++=*p2++ вместо *p1=*p2; p1++; p2++), если их использовать не рекомендуется?
3
31 августа 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=ShadyMan]Вообще-то это гораздо изящнее можно представить в таком виде:
if (stream=fopen("c:\\t.txt", "r"))
[/QUOTE]
Это не изящно, это ужастно!
Это ещё более отвратительно, чем вариант, который предложил Мerlin.
Это вносит путаницу, о чем даже предупреждает компилятор.
Вот объясни, чем предложенный тобой способ лучше ("изящнее"), чем запись в две строки?

[QUOTE=ShadyMan]
А интересно, зачем вообще в языке С допускаются сокращённые конструкции (например, *p1++=*p2++ вместо *p1=*p2; p1++; p2++), если их использовать не рекомендуется?[/QUOTE]
А зачем на спидометре 180 или даже 210 км/ч, если по городу 60, во шоссе 90, а по автостраде 120 ? :D

Иногда, это бывает полезно, но в большинстве случаев лучше писать понятный аккуратный код.
242
01 сентября 2006 года
Оlga
2.2K / / 04.02.2006
[quote=Green]Это не изящно, это ужастно!
Это ещё более отвратительно, чем вариант, который предложил Мerlin.
Это вносит путаницу, о чем даже предупреждает компилятор.

Вот объясни, чем предложенный тобой способ лучше ("изящнее"), чем запись в две строки?
[/quote]
а что непонятного в данной конструции? я не против простоты написания программ, но в данном случае все нормально, во всяком случае для C-программиста трудностей вызывать не должно, нагромождения нету.
3
01 сентября 2006 года
Green
4.8K / / 20.01.2000
Не аккуратно это, вот и все.

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

if (stream=fopen("c:\\t.txt", "r"))
if (stream==fopen("c:\\t.txt", "r"))

Например, бывает, что программист опечатался и не написал второй знак равенства. Если мы придерживаемся стиля, что в операциях сравнения у нас никогда не бывает операций присваивания, то такой ошибочный код выявляется просто при беглом просмотре.
Если же мы лепим и так и сяк, то нам придется логически осмысливать каждый такой участок кода. Что хотел сделать программитс? Присвоить или просто сравнить?

Для чего допускать такое, если это "лечится" одним махом?

Ну и ещё как-то более систематично писать:
1) открываем файл, получаем результат операции,
2) проверяем успешность операции открытия;
чем:
1) проверяем на успешность открытия результат получаемый в процессе открытия файла.
242
01 сентября 2006 года
Оlga
2.2K / / 04.02.2006
если с такой точки зрения, тогда согласна =)
спасибо
3.3K
01 сентября 2006 года
ShadyMan
191 / / 15.07.2006
[QUOTE=Green]Это не изящно, это ужастно!
Это ещё более отвратительно, чем вариант, который предложил Мerlin.
Это вносит путаницу, о чем даже предупреждает компилятор.
Вот объясни, чем предложенный тобой способ лучше ("изящнее"), чем запись в две строки?
[/QUOTE]
Этот способ изящнее, потому что в нём нет ничего лишнего. Писать
if ((stream=fopen("c:\\t.txt", "r"))!=NULL)
всё равно что if (true==true) или if (true!=false).
Если переменная stream уже сама по себе имеет значение либо "истина", либо "ложь" и этого достаточно для реализации алгоритма ветвления, нет никакой нужды специально создавать логическое выражение, которое, теоретически, должно быть сначала вычислено, а уже потом результат будет учтён оператором if. Конечно, умный компилятор всё равно выдаст один и тот же машинный код, но выглядит некрасиво. Да и лишние скобки не улучшат читабельности. А страх перепутать операторы = и == вообще отдаёт какой-то не то паскалевщиной, не то бейсиковщиной. :D
3
01 сентября 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=ShadyMan]Этот способ изящнее, потому что в нём нет ничего лишнего. Писать
if ((stream=fopen("c:\\t.txt", "r"))!=NULL)
всё равно что if (true==true) или if (true!=false).
Если переменная stream уже сама по себе имеет значение либо "истина", либо "ложь" и этого достаточно для реализации алгоритма ветвления, нет никакой нужды специально создавать логическое выражение, которое, теоретически, должно быть сначала вычислено, а уже потом результат будет учтён оператором if. Конечно, умный компилятор всё равно выдаст один и тот же машинный код, но выглядит некрасиво. Да и лишние скобки не улучшат читабельности.
[/QUOTE]
Это кустарщина, а не изящество.
А т.к. stream имеет не тип bool, и на сколько мне известно не имеет оператора приведения к типу bool, то хорошим стилем (для С++) будет все же написать логическое выражение, сравнив результат с конкретным значением, а не отдать это на волю компилятора.
На счет читабельности я уже сказал: хорошую читабельность обеспечивает лишь разбиение подобных "перлов" на две строки. А то, что ты обсасываешь, это теже штаны, что у Merlin, только вид сбоку.

Что лишнего в записи в две строки?
И что-то я так и не увидел изящества в твоем коде.
С таким же успехом можно применять сверхкороткие имена переменных типа: a,b,c, f1, вместо полноценных. Тоже "ничего лишнего". Можно не использовать ООП, чтоб не было "ничего лишнего", да много чего ещё можно сделать, чтоб записать всю программу в одну строчку. Только суть программного кода в другом - быть читабельным, интуитивно понятным и легко модифицируемым.

[QUOTE=ShadyMan]А страх перепутать операторы = и == вообще отдаёт какой-то не то паскалевщиной, не то бейсиковщиной. :D[/QUOTE]
Это не страх, это богатый опыт.
Кстати, это ещё принятая практика во многих серьезных командах, как впрочем и такая практика, как записывать в логических выражениях константы слева, а переменные справа.
Но ты вряд ли слышал и об этом.

P.S. Писать корявый, плоховоспринимаемый и некрасивый код - не признак профессионализма и крутости. А на счет "паскалевщины или бейсиковщины" ты, наверное, попытался меня обидеть? :D
Может посоревнуемся кто из нас лучше знает и умеет использовать C++? :D
Кстати, и на самый запутанный, но рабочий, код. :D
3.3K
01 сентября 2006 года
ShadyMan
191 / / 15.07.2006
Что касается типа bool... Так такого типа в языке С вообще нет. Какие тут могут быть приведения к нему? Причём тут компилятор, если это - стандарт языка?

Как вам такой примерчик?
Код:
int strtrim(char *str)
{
 char *src = str,*dst = str;
 while (isspace(*src))
  src++;
 do {
  while (*src && !isspace(*src))
   *dst++ = *src++;
  if (*src) {
   *dst++ = *src++;
   while (isspace(*src))
    src++;
  }
 } while (*src);
 if (dst != src && isspace(dst[-1]))
  dst--;
 *dst = 0;
 return dst - src;
}

Откуда, думаете, взят? - Из справки по стандартной библиотеке компилятора lcc. Это реализация известной функции, сделанная людьми, написавшими компилятор. Вполне работоспособный и неглючный. А вот ты, Green, пробовал когда-нибудь писать компилятор?

В том-то и прелесть языка С, что он бесконечно гибок. Конструкции, которые в других языках недопустимы, в нём могут быть использованы без проблем. А если кто-то сторонник пуританских правил (боже мой! константа позади переменной! четвертовать негодяя!), почему бы ему не писать на Паскале?

Но дело-то не в этом. А дело в дикой смехотворности ситуации. Посмотрите, как бесится Green (которого я, кстати, вовсе не собирался обижать)! Он и не подозревает, что приглашает соревноваться в С++ и ООП человека, который в этих вещах никогда разбираться и не пытался. Хочет зацепить меня словами о профессионализме, а моя профессия и близко не связана с программированием. Цирк, да и только.

(Закрываю голову руками, ожидая потока грязи, который на меня сейчас выльет Green, если, конечно, вообще пропустит мой пост на всеобщее обозрение - МОДЕРАТОР как-никак).
242
01 сентября 2006 года
Оlga
2.2K / / 04.02.2006
Цитата:
Что касается типа bool... Так такого типа в языке С вообще нет. ..


вы бы опредилились о каком языке идет речь, т.к. в C [COLOR="Blue"]bool[/COLOR] нет, а в C++ есть. A насчет цирка вы правы: форум не место для взаимных оскорблений и разборок, поэтому надо быть аккуратней в словах.

3.3K
01 сентября 2006 года
ShadyMan
191 / / 15.07.2006
Так я и говорю о C. На великий и могучий С++ и в мыслях не посигал! :)
3
01 сентября 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=ShadyMan]Что касается типа bool... Так такого типа в языке С вообще нет. Какие тут могут быть приведения к нему? Причём тут компилятор, если это - стандарт языка?
[/QUOTE]
Странно, что ты начал уточнять язык не в начале повествования.

[QUOTE=ShadyMan]
Как вам такой примерчик?
[/QUOTE]
Я не признаю авторитетов. :D
Если что-то не по мне, чихать я хотел на звания и ранги.

[QUOTE=ShadyMan]
В том-то и прелесть языка С, что он бесконечно гибок. Конструкции, которые в других языках недопустимы, в нём могут быть использованы без проблем.
[/QUOTE]
Ну, допустим, не бесконечно. Да и что называть гибкостью?
Кроме того, гибкость хороша пока она не становится синонимом анархии.

[QUOTE=ShadyMan]
А если кто-то сторонник пуританских правил (боже мой! константа позади переменной! четвертовать негодяя!), почему бы ему не писать на Паскале?
[/QUOTE]
Почему бы не ходить пешком, чтоб не задумываться о ПДД?
Подобные "пуританские" правила один из ключей к достижению успеха в командной разработке. Хочешь поговорить об этом?

[QUOTE=ShadyMan]
Посмотрите, как бесится Green (которого я, кстати, вовсе не собирался обижать)!
[/QUOTE]
Green никогда не беситься, т.к. ему доставляет удовольствие, когда бесятся другие. А сам он не допускает такой роскоши.

[QUOTE=ShadyMan]
Он и не подозревает, что приглашает соревноваться в С++ и ООП человека, который в этих вещах никогда разбираться и не пытался.
[/QUOTE]
А жаль... :(
Забавно было бы.

[QUOTE=ShadyMan]
(Закрываю голову руками, ожидая потока грязи, который на меня сейчас выльет Green, если, конечно, вообще пропустит мой пост на всеобщее обозрение - МОДЕРАТОР как-никак).
[/QUOTE]
Я придерживаюсь одного правила: поливаю грязью лишь написанный бред или полубред, сам человек, как объект посягательств, мне не интересен.
Кроме того, надо иметь серьезные аргументы, чтобы обвинять меня в злоупотреблении модераторскими привелегиями. Они (аргументы) у тебя есть?

Кажется мы отвлеклись от темы, как всегда перейдя на обсуждение моей личности. Безумно приятно, но может пора закрывать тему и сделать отдельную тему обо мне? :D
252
02 сентября 2006 года
koderAlex
1.4K / / 07.09.2005
Green в общем то прав . Дело в хорошем стиле . Если твою прогу в будущем планируется до(пере)делать , то хорошая структурированность (во слово загнул )) ) оччень поможет тому кто этим будет заниматься .
Вспомните нашу нац. поговорку : "проще написать свою прогу , чем разбираться в чужой" )))
3.3K
02 сентября 2006 года
ShadyMan
191 / / 15.07.2006
Раз Green не признаёт авторитетов, то, конечно, всё написанное дальше, ему по барабану, и он может это не читать. Только вот вопрос: если сам не признаёшь авторитетов, почему думаешь, что другие будут признавать твой?

Вот несколько примеров из "Win32 Developer's References".

if (waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER,
(LPWAVEFORMAT)pFormat,
(LONG)hwndApp, 0L, CALLBACK_WINDOW)){...}

if ((lpData = GlobalLock(hData)) == NULL){...}
(Последнее больше в стиле Merlin'a, но, заметьте, здесь сравнение идёт именно с нулём, а не с не-нулём. Эта конструкция, конечно, более читабельна, чем
if (!(lpData = GlobalLock(hData))){...}. Тут я не спорю).

xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
Green бы, наверное, посоветовал вместо ? и : использовать if и else. Или нет?

if (!OnCreate(hwnd)){...}

А следующий пример из книги Ю. Ю. Громова и С. И. Татренко "ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ СИ":
if((r=p->n)==NULL) sum+=m[j++].val*inp;

Подобных примеров в программистской литературе масса. А если уж ставить вопрос о читабельности ребром, так надо уточнить, читабельность для кого: для программиста или школьника? Когда я впервые увидел приведённый уже пример
Код:
int strtrim(char *str)
{
 char *src = str,*dst = str;
 while (isspace(*src))
  src++;
 do {
  while (*src && !isspace(*src))
   *dst++ = *src++;
  if (*src) {
   *dst++ = *src++;
   while (isspace(*src))
    src++;
  }
 } while (*src);
 if (dst != src && isspace(dst[-1]))
  dst--;
 *dst = 0;
 return dst - src;
}

я понял из него только то, что, оказывается, совсем не знаю С. Но потом ведь разобрался, и ничего непонятного и неудобоваримого в подобных конструкциях для меня больше нет. А если фанатично следовать принципу удобочитаемости, так можно сказать, что и a=b+c*d - слишком сложная конструкция. Вдруг программист ошибся и забыл, что сначала с будет умножено на d, а уже потом всё остальное. Может, он имел ввиду a=(b+c)*d. Так давайте введём промежуточную переменную и напишем e=c*d; a=b+e. Так что ли по Green'у? Поймите, я вовсе не считаю, что нужно специально лепить всё в одну кучу и делать такие конструкции, в которых сам чёрт ногу сломит. Но что такого кошмарного в выражении *dst++ = *src++, когда знаешь приоритет одних операторов перед другими, не пойму, хоть убейте.

Разговаривать о "ключах к успеху в коммандной разработке" мне неинтересно. Я повторяю, что я не программист и не отношусь к касте избранных, получающих бешенные бабки за просиживание штанов в кондиционируемых офисах. ("Здесь Паша Эмильевич, обладавший сверхъестественным чутьем, понял, что сейчас его будут бить, может быть, даже ногами"). :)
3.0K
02 сентября 2006 года
Мerlin
267 / / 25.07.2006
imho пора бы закрыть эту ветку, так как из-за самых мизерных вопросов, возникают самые дурацкие споры.

[QUOTE=ShadyMan]<...skipped...>Последнее больше в стиле Merlin'a, <...skipped...>[/QUOTE] Уже двое заговорили о моем стиле. Вынужден вас разочаровать, это не мой код. Перед тем как написать код, я посмотрел help по fgets(). В MSDN был пример:
Код:
#include <stdio.h>

int main( void )
{
   FILE *stream;
   char line[100];

   if( (stream = fopen( "crt_fgets.txt", "r" )) != NULL )
   {
      if( fgets( line, 100, stream ) == NULL)
         printf( "fgets error\n" );
      else
         printf( "%s", line);
      fclose( stream );
   }
}
и я в этом примере, только изменил середину, чтоб делала то-что надо
Код:
FILE *stream;
  char line[100];
 
  if((stream = fopen("C:\\t.txt", "r"))!=NULL)
  {
    while(fgets(line, 100, stream)!=NULL)
    {
      char *lc = strtok(line, " ");
      int x = atoi(lc);
      ...
    }
    fclose(stream);
  }
Адрес примера на сайте Microsoft: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_fgets.2c_.fgetws.asp

Раньше, когда Green "волосы себе рвал", что "что за нечеловеческий код", я не признавался в плагиате, так как посчитал, что то что он считает мой код нечеловеческим, то это его личная проблема. Пусть он уж как-то сам со своей проблемой справится. У Эзопа была басня, о мужике, сыне и осле. Шли троем на дороге никого не трогали, но каждый прохожий имел свое мнение:
1. Надо, чтоб отец на осле сидел,
2. Надо, чтоб сын на осле сидел,
3. Надо чтоб оба на осле сидели,
4. Надо, чтоб они двое несли осла... И они так и делали. В конце уже осел сидел на их шее. :)

Что-то подобное происходит и в С++. На сайте sources.ru, кто-то выставил программу из 10-15 операторов, и сказал, что этот код не компилируется. Он начинающий и не знает, в чем проблема? Посмотрев код, один крутой знаток стандарта С++ пришел к выводу, что если он пишет такой код, то он не разбирается в С++. На что тот ответил, так это не мой код. Это первая программа из книги Eckela: "Thinking in С++"

Можно выдумать какой-то супер алгоритм для решения какой-то задачи и написать программу. Если эта программа написана на паскаль, vba, php
итд, то она будет считаться хорошей программой. А если написана на С++, то всегда может найтись какой-то умник, кто скажет: вот этот if не так нужно писать, потому-что код неудобочитаем. И если кто-то будет менять программу, то может не разобраться. Но, imho, если кому-то трудно разобраться в какой-то команде if, то ему нефиг лезть в чужую программу.
3
02 сентября 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=ShadyMan]Раз Green не признаёт авторитетов, то, конечно, всё написанное дальше, ему по барабану, и он может это не читать. Только вот вопрос: если сам не признаёшь авторитетов, почему думаешь, что другие будут признавать твой?
[/QUOTE]
А я и не думаю об этом. Я просто привожу аргументы в защиту своего варианта:
1) это читабельнее,
2) это избавляет от потенциальных ошибок,
3) это удобнее отлаживать, т.к. я могу пошагово пройтись отладчиком по обоим строчкам.

Пока я услышал один аргумент от тебя, который весьма субъективен: "это изящно".

Счет 3:1 ?

[QUOTE=ShadyMan]Вот несколько примеров из "Win32 Developer's References".
<skip>
[/QUOTE]
Да, неудачные примеры. Почему? См. мои аргументы чуть выше.

[QUOTE=ShadyMan]
xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
Green бы, наверное, посоветовал вместо ? и : использовать if и else. Или нет?
[/QUOTE]
Нет, я использую '?', но данное выражение я бы разбил на два: в первом получение значения по условию, во втором вычисление всего остального:
val = tm.tmPitchAndFamily & 1 ? 3 : 2;
xUpper = val * xChar/2;
Опять же см. аргументацию выше.
Имя переменной val, конечно же должно быть значимым, а не просто val.

[QUOTE=ShadyMan]
if (!OnCreate(hwnd)){...}
[/QUOTE]
Хм... а где тут присвоение внутри if ?
Что-то ты начинаешь сбиваться с темы нашего спора.

[QUOTE=ShadyMan]
А следующий пример из книги Ю. Ю. Громова и С. И. Татренко "ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ СИ":
if((r=p->n)==NULL) sum+=m[j++].val*inp;
[/QUOTE]
Да... жуть...
Ты сам этого не замечаешь? Или так же считаешь, что это "изящно"?

[QUOTE=ShadyMan]
Подобных примеров в программистской литературе масса. А если уж ставить вопрос о читабельности ребром, так надо уточнить, читабельность для кого: для программиста или школьника?
[/QUOTE]
А какая разница?

[QUOTE=ShadyMan]
Когда я впервые увидел приведённый уже пример
<skip>
Но потом ведь разобрался, и ничего непонятного и неудобоваримого в подобных конструкциях для меня больше нет.
[/QUOTE]
Да код то вполне читабелен. Я совершенно не вижу в нем ничего, что похоже на то, о чем мы спорим. Ты постоянно переключаешься на совершенно иные примеры, не имеющие ничего общего с твоим кодом и причиной спора.

[QUOTE=ShadyMan]
А если фанатично следовать принципу удобочитаемости, так можно сказать, что и a=b+c*d - слишком сложная конструкция. Вдруг программист ошибся и забыл, что сначала с будет умножено на d, а уже потом всё остальное. Может, он имел ввиду a=(b+c)*d. Так давайте введём промежуточную переменную и напишем e=c*d; a=b+e. Так что ли по Green'у?
[/QUOTE]
Перегибаешь палку. Так любое мнение можно возвести в степень абсурда.

[QUOTE=ShadyMan]
Поймите, я вовсе не считаю, что нужно специально лепить всё в одну кучу и делать такие конструкции, в которых сам чёрт ногу сломит. Но что такого кошмарного в выражении *dst++ = *src++, когда знаешь приоритет одних операторов перед другими, не пойму, хоть убейте.
[/QUOTE]
Еще раз спрашиваю, какое отношение это имеет к теме разговора: присваивание в if ?

[QUOTE=ShadyMan]
Разговаривать о "ключах к успеху в коммандной разработке" мне неинтересно. Я повторяю, что я не программист и не отношусь к касте избранных, получающих бешенные бабки за просиживание штанов в кондиционируемых офисах. ("Здесь Паша Эмильевич, обладавший сверхъестественным чутьем, понял, что сейчас его будут бить, может быть, даже ногами"). :)[/QUOTE]
А я вот говорю о профессиональном программировании и профессиональных подходах и не только в командной разработке. А кому это интересно, показываю элементы кустарщины и подводные камнях в "наколеночном" коде.

Неинтересно? Тогда для чего спорить?
Сказал бы: "я не профессионал, я делаю программы для себя и мне всё равно, как они написаны."
3
02 сентября 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=Мerlin]Уже двое заговорили о моем стиле. Вынужден вас разочаровать, это не мой код.
[/QUOTE]
Я не утверждал, что это "твой стиль". Я говорил о стиле, в котором пишешь ты.

[QUOTE=Мerlin]
Перед тем как написать код, я посмотрел help по fgets().
<skip>
[/QUOTE]
Да, в моем понимании отвратный стиль. И что такого, что он есть в MSDN, там есть код с ошибками и по-грубее. И что из этого? MSDN - сборник идеальных примеров? Мерило стиля для всех?
Заметь, я привожу как минимум три внятных аргумента (см. предыдущий пост), ты же приводишь единственный аргумент: "потому что так делают другие". Несерьезно.

[QUOTE=Мerlin]
Раньше, когда Green "волосы себе рвал", что "что за нечеловеческий код", я не признавался в плагиате, так как посчитал, что то что он считает мой код нечеловеческим, то это его личная проблема. Пусть он уж как-то сам со своей проблемой справится. У Эзопа была басня, о мужике, сыне и осле. Шли троем на дороге никого не трогали, но каждый прохожий имел свое мнение:
1. Надо, чтоб отец на осле сидел,
2. Надо, чтоб сын на осле сидел,
3. Надо чтоб оба на осле сидели,
4. Надо, чтоб они двое несли осла... И они так и делали. В конце уже осел сидел на их шее. :)
[/QUOTE]
Однако в этой басне не один прохожий, а как минимум трое... :)
Мысль понятна? Или огласить ники? :)

[QUOTE=Мerlin]
Можно выдумать какой-то супер алгоритм для решения какой-то задачи и написать программу. Если эта программа написана на паскаль, vba, php
итд, то она будет считаться хорошей программой. А если написана на С++, то всегда может найтись какой-то умник, кто скажет: вот этот if не так нужно писать, потому-что код неудобочитаем. И если кто-то будет менять программу, то может не разобраться. Но, imho, если кому-то трудно разобраться в какой-то команде if, то ему нефиг лезть в чужую программу.
[/QUOTE]
Ну мне ваша позиция давно понятна: не важно "как", важно "что" написано. Я придерживаюсь несколько иного: важно и "что" и "как", т.к. как написано влияет на то что написано.

P.S. Не льсти себе, я волосы от твоего кода себе не рву. А подправить его мне даже доставляет удовольствие, впрочем, как и поспорить конструктивно, жаль, что конструктива не много. Я так и не понял, почему надо писать так, как пишут в приведенных тобой и ShadyMan примерах? :D
Так что "пеши исчо"!
3.3K
02 сентября 2006 года
ShadyMan
191 / / 15.07.2006
Если речь идёт только об одном присвоении в if, то, действительно, тема выеденного яйца не стоит. Дело вкуса. А вот аргумент ты выставил только один: "это избавляет от потенциальных ошибок". Два других не принимаются. Если ты об известном фрагменте кода пишешь: "Да код то вполне читабелен", - то и присвоение в if должен понимать без проблем. А отлаживать код удобнее всего в ассемблерном виде, если уж на то пошло. Там точно каждый шаг будет виден. Остаются только потенциальные ошибки. Но и этот аргумент слаб, потому что касается только тех, кто одновременно пишет на разных языках. Опытный программист С такой ошибки никогда не сделает. Потенциальная путаница между = и == - это особенность языка С вообще, а не недостаток конструкции "присвоение внутри if". Мой же аргумент вполне логичен: изящно, потому что ничего лишнего. Какая-нибудь жирная тётка имеет явные преимущества в случае ОШИБКИ штурмана и кораблекрушения: она и на плаву лучше будет держаться и без еды несколько месяцев протянет. Но меня почему-то больше привлекают ИЗЯЩНЫЕ девушки.
242
02 сентября 2006 года
Оlga
2.2K / / 04.02.2006
[quote=ShadyMan]
...Какая-нибудь жирная тётка имеет явные преимущества в случае ОШИБКИ штурмана и кораблекрушения: она и на плаву лучше будет держаться и без еды несколько месяцев протянет. ...[/quote]
рассмешил :D . с каких пор излишний вес способствует устойчевости в воде?
п.с. до каких высот только может довести человека свобода мышления :) с мсдн закончили, пошли примеры из жизни
3
02 сентября 2006 года
Green
4.8K / / 20.01.2000
[QUOTE=ShadyMan]Если речь идёт только об одном присвоении в if, то, действительно, тема выеденного яйца не стоит. Дело вкуса. А вот аргумент ты выставил только один: "это избавляет от потенциальных ошибок". Два других не принимаются. Если ты об известном фрагменте кода пишешь: "Да код то вполне читабелен", - то и присвоение в if должен понимать без проблем. А отлаживать код удобнее всего в ассемблерном виде, если уж на то пошло. Там точно каждый шаг будет виден. Остаются только потенциальные ошибки. Но и этот аргумент слаб, потому что касается только тех, кто одновременно пишет на разных языках. Опытный программист С такой ошибки никогда не сделает. Потенциальная путаница между = и == - это особенность языка С вообще, а не недостаток конструкции "присвоение внутри if". Мой же аргумент вполне логичен: изящно, потому что ничего лишнего. Какая-нибудь жирная тётка имеет явные преимущества в случае ОШИБКИ штурмана и кораблекрушения: она и на плаву лучше будет держаться и без еды несколько месяцев протянет. Но меня почему-то больше привлекают ИЗЯЩНЫЕ девушки.[/QUOTE]
Извини, я привык технические аспекты аргументировать техническими терминами. Подобные метафоры глупы, т.к. не имеют никакой связи с реальностью.

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

Что значит "изящный" в твоем коде? Чем запись в две строки менее изящна? Тем что придется ещё раз (целый раз!) написать имя переменной? :D
Да... огромная цена за потенциальную безопасность, читабельность и отлаживаемость!

Отлаживаться в ассемблере? :D
М-да... воистину времени дофига, если делать нефига! :D

Советуешь отлаживаться в ассемблере сразу подо все платформы под которые пишешь?
А нафига вообще тогда языки программирования?

Пройдемся по аргументации, которую ты так лихо отмел. Ответь на вопросы:
1. Ты считаешь, что код
if((stream = fopen("C:\\t.txt", "r"))!=NULL)
более читабелен, чем
stream = fopen("C:\\t.txt", "r");
if(stream != NULL)


2. Ты считаешь, что год
if((stream = fopen("C:\\t.txt", "r"))!=NULL)
проще отлаживать, чем
stream = fopen("C:\\t.txt", "r");
if(stream != NULL)


3. Ты считаешь, что ошибку проще найти в коде
if((stream = fopen("C:\\t.txt", "r"))!=NULL)
чем в коде
stream = fopen("C:\\t.txt", "r");
if(stream != NULL)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог