| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Для новичков > не правильный тип возвращаемого значения функции |
| Автор: n199a 27.1.2014, 04:13 | ||
| При компиляции вылазит: error: expected primary-expression before '=' token error: 's' was not declared in this scope warning: deprecated conversion from string constant to 'char*' Но если obr и showword сделать отдельно, то всё нормально компилируется. Ошибка кроется в типах возвращаемых значений для функций...
|
| Автор: 586 27.1.2014, 06:38 |
| Первых двух ошибок в коде нет. Третью ошибку (точнее не ошибку, а warning) можно убрать, объявив функцию так: void showword(char *s, const char *divider){ Еще компилятор может выдавать предупреждение на строчку №3. Исправить можно так: if((s = strtok(s, divider))!=NULL){ Строчка №6 несовсем корректно написана, замени «'\0'» либо на «NULL» либо на «0». showword(NULL, divider); В функции obr не хватает вызова функции free. |
| Автор: n199a 27.1.2014, 11:26 | ||
Вот, глянь, весь код:
|
| Автор: xvr 27.1.2014, 12:20 | ||
Ошибка тут -
А вообще код ужасен - дикая помесь С и С++, и goto в придачу |
| Автор: n199a 27.1.2014, 12:25 | ||
Ну да. Дают материал на Си, а я С++ читаю. Вот приходится смешивать, брать кусками, что знаю С текстом материал просто не внимательно читал, пришлось в просторах интернета искать решение. А чего goto так недолюбливают? Код действительно плох, ещё в придачу вылазит:
Почему #define лишний? Без его нормально скомпилировалось.... P.S. Читаю Хенкеманс, Ли - Программирование на С++, может стоит другое почитать? Добавлено через 5 минут и 35 секунд Что посоветуешь изменить? Не оставлять же его в таком виде |
| Автор: xvr 27.1.2014, 12:47 |
Лишний не он, а знак '=' в нем А того, что его надо использовать только там, где без него никак не обойтись. В данном случае классический цикл (for(;;) ) и без goto точно обойтись можно Ну либо С либо С++. И уж точно не std::cout и malloc/free/strdup вместе! А рекурсивный showword по заданию требовался? Такой метод разбиения на слова не самый лучший, мягко говоря |
| Автор: n199a 27.1.2014, 15:00 | ||
Вот написал новый. Почему, когда нажимаю 3, то сразу выскакивает "Press the key ", без предложения ввода строки "Enter stroku: " ?
|
| Автор: xvr 27.1.2014, 17:21 | ||||
Можно еще проще:
Нельзя смешивать ввод вывод через потоки С++ и С FILE на одном и том же файле (в вашем случае на STDIN/STDOUT) Кстати, вашу функцию можно сделать и рекурсивной - тогда массив на слова не понадобится (но и strdup вкупе с free тоже не нужен)
Собственно очень похоже на ваш первоначальный вариант, но без лишних манипуляций с динамической памятью. PS. Я просмотрел, что вам надо было развернуть слова в обратном порядке - тут рекурсивная версия выглядит вполне ничего |
| Автор: trinitr0 27.1.2014, 17:38 | ||
Потому что: 1. Нарушает парадигму структурного программирования (последовательность выполнения) 2. Препятствует оптимизации компиляторами управляющих структур 3. Может нарушать логику программ 4. Может приводит к деградации производительсности (из-за сброса и переинициализации конвейров CPU) 5. Непредсказумое значение иницилизированных переменных до их применения 6. Пропуск инициализации при входе в цикл 7. Пропуск пролога при выходе из функции Ещё в далёком 1968г Эдсгер Дейкстра написал http://khpi-iip.mipk.kharkiv.edu/library/extent/dijkstra/pp/ewd215.html |
| Автор: n199a 27.1.2014, 18:26 | ||
Использовал вашу функцию, всё равно сразу вылазил Press the key ... Добавлено через 1 минуту и 28 секунд Я ещё такого не изучал. |
| Автор: xvr 27.1.2014, 21:32 | ||
Enter stroku: даже не выводит? Или все же выводит, но строку не вводит? Если второе, то это правильно - предыдущий cin >> key прочел число, а вот перевод строки в буфере остался, вот он пустую строку и вводит |
| Автор: n199a 27.1.2014, 23:37 | ||
Enter stroku выводит. А что тогда делать с буфером? |
| Автор: akizelokro 28.1.2014, 00:25 | ||||||||
Чё это у вас?
при столкновении с ARRAYSIZE приводит к забавным эффектам (фикх отыщещь). например. Да и -1 может возвратить
никто так не пишет. можно
а предыдущий вариант может относиться только к трюкам, либо к непредсказуемым последствиям и противоречит логике функции 'strtok'. Не говоря уже, что лучше s получить в стеке в порядке разбора аргументов функции showword и оставить временно в покое. Потом же у функции showword идёт рекурсивный вызов.
здесь рисуется memory leak. Неделю пил, но strdup, походу, программер должен подчищать самостоятельно. Так что istr переобозначать не надо. "Шоб було" и "этапы большого пути". |
| Автор: xvr 28.1.2014, 08:36 |
Очищать. cin.ignore(1000,'\n') |
| Автор: n199a 28.1.2014, 09:13 |
Не работал просто с таким. И по этому возникает сопутствующий вопрос - в какое место в коде вставлять? |
| Автор: xvr 28.1.2014, 12:25 |
Перед cin.getline() |
| Автор: n199a 28.1.2014, 12:29 |
Нету такого в коде. |
| Автор: xvr 28.1.2014, 12:30 |
У меня в примере есть. У вас стоит gets() - это работать нормально не будет |
| Автор: n199a 28.1.2014, 12:46 | ||
Сделал так, но теперь не меняет местами:
|
| Автор: akizelokro 29.1.2014, 00:38 |
| int obr() { cout << "Vvedite stroku: "; string s; cin >> s; char * word = s.data(); vector <char *> for_reverse; const char delimiter[] = ".,"; // не попадёт /n while(word = strtok(word, delimiter) { for_reverse.push_back(word); } for(auto rit = for_reverse.rbegin(); rit!= for_reverse.rend(); ++rit) cout >> *rit >> " "; cout >> endl; } // звязывайте уже с этим // первоначально шёл и такой коад как // char * s; // cin >> s. но код был реально плох. |
| Автор: n199a 29.1.2014, 00:45 | ||
А без векторов обойтись можно? |
| Автор: akizelokro 29.1.2014, 00:45 |
| ах, да, сin >> ругается на два char* подряд. Добавлено @ 00:59 можно. используя вообще Сшниый стиль. const char delimiter[] = ".,"; puts("Taschi stroku:"); char * str = gets(); char * pointers = calloc((strlen(str) + 1) * sizeof(char *)); // а, лень free делать. и sizeof надо по трезвяни вспомнить char * word = str; int i = 0; while(word = strtok(word, delimiter)) { (pointers + i * sizeof(char *)) = word; i++; } for(int q = (strlen(pointers)/sizeof(char *)); q > 0; q--) { printf("%s ", pointers + (q - 1) * sizeof(char *)); // puts(pointers + (q - 1) * sizeof(char *)); // puts(" "); } Пару раз откомпильнуть, а так пример кажисть работоспособный. Мне тут понравилось самому как я у указателей стал длину строки брать |
| Автор: akizelokro 29.1.2014, 01:11 |
| Ну, тут малость намутил, но после пары компиляций (и правки ошибок) работать должно. |
| Автор: xvr 29.1.2014, 10:33 |
Потому что у вас теперь разделитель не пробел, а набор запятых (строка 5 в листинге). Так что у вас получается ровно 1 слово (во всю строку). И менять местами просто нечего. |
| Автор: n199a 29.1.2014, 14:37 | ||
Точно, забыл, что менял на запятую, точку и слэш Благодарю всех за участие |
| Автор: akizelokro 31.1.2014, 02:00 |
| разоврался с пойнтерами, ещё вчера хотел заметить. но пример работосопсобный, и ненамного длиньше, чем с С++ |