|
|
|
| Люди помогите балбесу, 2 неделю пишу программу со строками. Условие задачи следующее
Дана строка, состоящая из групп нулей и единиц. Каждая группа отделяется друг от друга одним или несколькими пробелами.
Вывести на экран первые символы строки, равные количеству символов самой длинной группы.
Help me please. | |
|
|
|
|
|
|
|
для: M@M@Z0GL0
(16.12.2008 в 22:10)
| | какими функциями пытались делать ?
тоже чевойто со строками не разберусь никак , только стандартными сишными функциями хотел
, без strlen(), но почемуто у меня sizeof() всегда показывает 4 со строками, а читал где-то что должен размер строки показывать. Надо попробовать другим компилятором,
#include <stdio.h> // sscanf() printf()
#include <conio.h> // getch();
#include <malloc.h> // calloc() free()
#include <string.h> // strlen()
main() {
char *str = "111111 000000 11 111111111 00 111";
char *bf;
int p=0;
if( (bf = (char *)calloc(512, sizeof(char))) == NULL)
return 1; // выделение памяти или return
char *gc = (char *)calloc(1, sizeof(char));
while (sscanf( &str[p], "%s*", bf)
&& (p += strlen(bf)) < strlen(str)) {
while (sscanf(&str[p+1], "%c", gc)
&& gc == " ") { p++; } // здесь баг
/* хотел применить getc() вместо второго sscanf()
но просто отказалось работать. */
printf("%s\n %i\n", bf, p);
}
free(gc);
free(bf); // освободить память
getch();
return 0;
} |
У меня такой вопрос , извиняюсь что в не своей теме ,)
функция getc() обычно работает с указателем на память ?
, как пытался сделать getc(&bf[1])
и почему второй sscanf() не хочет считать пробелы ?
вроде должен считать , если "%c" (пробовал "%Fc", "%Nc", не работает на DevCpp) | |
|
|
|
|
|
|
|
для: exp
(17.12.2008 в 03:33)
| | но почемуто у меня sizeof() всегда показывает 4 со строками, а читал где-то что должен
размер строки показывать. Надо попробовать другим компилятором, |
Дело не в компиляторе, а в понимании.
sizeof(str) выдает размер указателя на строку, а он чаще всего будет 4 байта
а sizeof str должен как раз выдать длину строки.
MSDN:
Yields the size of its operand with respect to the size of type char.
sizeof unary-expression
sizeof ( type-name )
Remarks
The result of the sizeof operator is of type size_t, an integral type defined in the include file
STDDEF.H. This operator allows you to avoid specifying machine-dependent data sizes in your
programs.
The operand to sizeof can be one of the following:
A type name. To use sizeof with a type name, the name must be enclosed in parentheses.
An expression. When used with an expression, sizeof can be specified with or without the
parentheses. The expression is not evaluated. |
| |
|
|
|
|
|
|
|
для: GeorgeIV
(17.12.2008 в 09:25)
| | у меня выдаёт длинну строки только если строка объявлена как char str[37]
, а c указателем даже на такие-же char не смог придумать как посчитать строку
попробовал по другому решить предложенную задачку, но не смог избавиться от strlen()
#include <stdio.h>
#include <conio.h>
#include <string.h> // strlen
int main() {
int t, i,i2, l2s, max=0;
static char str[37] = "1111 000000 11 111111111 00 111";
char bf[512];
printf("\n sizeof %i\n\n", sizeof str);
for(i=0; 1; i = i2) {
if( sscanf(&str[i], "%s", &bf)< 0) break;
//sscanf не захватывает пробельные символы
l2s = strlen(bf);//
if (max<l2s) max = l2s;
for(i2=i+l2s; 1; i2++){ // пропуск пробелов 0x20=" "
if (str[i2] != 0x20) break;
}
printf(" bf = %s\n", bf);
} // end of for
printf("\n max = %i\n\n\n", max);
i=-1;
while((i+=1) < max) printf("%c", str[i]); // вывод max символов строки
getch();
return 0;
} |
Не уверен в правильности и оптимальности написания | |
|
|
|
|
|
|
|
для: EXP
(17.12.2008 в 18:07)
| | Мельком посмотрел
for(i2=i+l2s; 1; i2++){ // пропуск пробелов 0x20=" "
if (str[i2] != 0x20) break;
}
|
Можно заменить на
for (i2=i+l2s; str[i2]==0x20; i2++);
|
| |
|
|
|
|
|
|
|
для: exp
(17.12.2008 в 03:33)
| | exp
Не знаю как тебя благодарить. Спасибо тебе огромное, единственное что я заменил, это ручной ввод строки и
sizeof на i=strlen (str).
Спасибо еще раз. | |
|
|
|
|
|
|
|
для: M@M@Z0GL0
(17.12.2008 в 22:25)
| | я и сам тут пробую разобраться ,) можно заменить strlen() на свою strlen() такую как дальше в коде
попробовал теперь пересобрать проект как с++
и опять не пойму почему не все переменные адекватно перемениваются .)
#include <stdio.h>
#include <conio.h> // detch()
int strlen(char *s) {
int y = 0;
while(s[y] != 0) y++;
return y;
}
typedef struct xstr{
char *v;
int size;
int count;
xstr(int sz, char * str) {
v = new char[size=sz]; // выделение памяти
count = strlen(str);
}
~xstr() { delete v; }
} xstr;
typedef struct ystr{
char *v;
int size;
int count;
ystr(int sz) { v = new char[size=sz]; // выделение памяти
count = 0;
}
~ystr() { delete v; }
} ystr;
int main() {
ystr ybf(512);
ybf.v = "1234567890 1234567890";
printf("\n ybf.count %i\n ybf.size %i\n strlen %i\n\n"
, ybf.count, ybf.size, strlen(ybf.v));
xstr bf(512, ybf.v);
printf("\n bf.count %i\n bf.size %i\n strlen %i\n\n"
, bf.count, bf.size, strlen( bf.v ));
getch();
return 0;
} |
Никак не соображу почему с объектом bf strlen( bf.v ) возвращает как-будто размер обьекта а не строки
и как-нибудь можно-ли оптимально сделать так чтобы при создании объекта не надо было-бы указывать сколько памяти выделять, а автоматически выделялось-бы,
и как добавить метод strlen() или переопределить какой-нибудь оператор, чтобы возвращало размер строки ? | |
|
|
|
|
|
|
|
для: exp
(18.12.2008 в 11:43)
| | вообще то полагается используя массивное new[] использовать массивное delete[] для удаления объекта
После инициализации есть только присвоение одного указателя другому, а автоматического пересчета в структуре естественно не будет
Еще одно замечание - память выделена, но не проинициализирована, завершающего нуля нет, поэтому длина считается до первого попавшегося нуля в памяти после структуры. И с удалением не совсем понятно, они же создаются на стеке и применение оператора delete , по крайней мере в Студии 2008 вызывает ошибку
PS Вобщем программа ведет себя согласно написанному коду. | |
|
|
|
|
|
|
|
для: GeorgeIV
(18.12.2008 в 16:46)
| | Небольшие вариации:
// for(i2=i+l2s; 1; i2++){ // пропуск пробелов 0x20=" "
// if (str[i2] != 0x20) break;
// }
while(str[i2=i+l2s++] == ' '); |
//i=-1;
//while((i+=1) < max) printf("%c", str[i]); // вывод max символов строки
str[max] = 0;
printf("%s", str); |
| |
|
|
|
|
|
|
|
для: GeorgeIV
(18.12.2008 в 17:17)
| | по условиям , если я правильно понял надо что-то вроде
printf("%.9s", str);
но для этого сначала пришлось-бы сгенерировать такую строку формата в зависимости от того сколько символов.
А функциями типа putch() выводить не решился,) на случай возможности отказаться от <conio.h>
, в которой вроде-бы по старой старой документации должна быть функция cscanf(), которую почемуто у меня нет , но есть например _cscanf("%s", bf); , которая совсем очень странно себя ведёт :)
и много других отсутствующих функций находится , если добавить '_'
, неверное это какие-то фичиасмомакросы devcpp :) но приятно иногда использовать _beep(...) вместо putch(7) ;)
насчёт стека думаю это та память которая встроена в сам процессор,
вообще не очень понимаю отличается-ли то где будет размещено содержимое переменной
взависимости от того просто-ли её объявили как char var[123] или использовали var = new char[123],
думаю только что те строки что написаны в коде программы и не изменяются наверное лучше как
static char *str='123'
а со всеми другими уже какие-то сложности, и иногда не похоже что например f(* link) применяет f к самому объекту на который указывает link, а f(&obj) делает что-то с указателем на obj.
Буду пробовать начинать читать всё внимательнее.
Спасибо ;) | |
|
|
|
|
|
|
|
для: exp
(18.12.2008 в 21:28)
| | интересно таки работает это _cscanf()
можно не записывая никаких пробелов получить чистые данные из ввода с командной строки
и создать массив индексов подстрок, посчитать длинну ,и всё это ещё во время только печатания
но не работает :)
int u = i=0;
int len, keys[55]; // длинна строки и адреса подстрок
while (_cscanf("%s", &bf[i])) {
len = strlen(bf); // printf("\n%.s %i\n", bf, (len = strlen(bf)));
keys[u++] = i;
i = len;
if (getch() == 0x0d) break; // "\n"
}
printf("\n string = %s\n\n", bf);
printf(" keys = \n");
u = 0;
while(keys[u]< sizeof bf) {
printf(" %i\n", keys[u]);
u++;
}
getch(); | не хочет срабатывать как нужно if (getch() == 0x0d) break; // "\n"
0x0a // "\r" тоже пробовал ;)
если перед нажатием enter есть пробелы ничего не происходит,
:) | |
|
|
|
|
|
|
|
для: exp
(18.12.2008 в 21:28)
| | насчёт стека думаю это та память которая встроена в сам процессор,
вообще не очень понимаю отличается-ли то где будет размещено содержимое переменной
взависимости от того просто-ли её объявили как char var[123] или использовали var = new char[123],
думаю только что те строки что написаны в коде программы и не изменяются наверное лучше как
static char *str='123' | Этот кусок показывает, что у вас еще каша в голове по сям.
Если очень упрощенно, стэк принадлежит только данной программе и разрушается вместе с ней. Созданное на стеке самому уничтожать не надо. Так создаются все локальные переменные.
Общая память (куча,heap) принадлежит всем и именно в ней создаются динамические объекты, и то, что вы там создали в сях надо уничтожать самому, иначе возникает утечка памяти.
Варианты с _ появились с введением микрософтом "безопасных" функций, которые позволяют, например, не допустить переполнения буфера. Также существуют функции с _, кторые в зависимости от установок среды работают с типом TCHAR как с char или как с wchar_t.
Если строка не изменяется, и вообще какой то объект, лучше его объявлять как const. Поведение квалификатора static зависит еще от того, в каком месте он использован.
Но это лучше все читать в спецлитературе, MSDN всегда должен быть под рукой, в нем есть все ответы. | |
|
|
|
|
|
|
|
для: GeorgeIV
(19.12.2008 в 10:03)
| | Одиночный символ ставится в одинарные кавычки '\r' надоб было использовать. В двойные кавычки заключается строка.
Мне кажется с помощью scanf эту задачу не решить, потому как она не различает все непечатные символы и пока в буфере не будет хоть одного символа , внутрь while прога не войдет. | |
|
|
|
|
|
|
|
для: GeorgeIV
(19.12.2008 в 10:13)
| | MSDN для меня это ещё хуже чем Perldoc в Perl :)
английский пока понимаю слово через четыре , ито если про програмирование пишут :)
Спасибо | |
|
|
|
|
|
|
|
для: exp
(19.12.2008 в 12:06)
| | А что делать! Без английского в программировании беда. Сам изучаю его только ради понимания тех.документации | |
|
|
|
|
|
|
|
для: exp
(18.12.2008 в 11:43)
| |
а может
| |
|
|
|
|
|
|
|
для: exp
(17.12.2008 в 03:33)
| | не будишь-ли ты так любезен и мне помочь в моей задачке ? | |
|
|
|
|
|
|
|
для: M@M@Z0GL0
(16.12.2008 в 22:10)
| | Уважаемые гении С++ не один M@M@Z0GL0 такой, у меня задание из этой же оперы !
Ему я вижу помогли ! Если Вам не трудно помогите и мне, никак сам сделать не могу, одни ошибки и ничего не работает !
Мое задание:
Дана строка, состоящая из групп нулей и единиц. Каждая группа отделяется друг от друга одним или несколькими пробелами.
Подсчитать количество единиц в самой короткой группе !
Заранее ОГРОМНЕЙШЕЕ СПАСИБО ! | |
|
|
|
|
|
|
|
для: WveB
(20.12.2008 в 15:25)
| | зачем обзываться гениями C++ ? :)
каким компилятором пробовали ? ругаются-ли на какой-нибудь код из этой темы, или на что ругается?
компилируется-ли например этот код слегка похожий на задачку ?
#include <conio.h>
int main() {
char bf[512], x;
int i, cur, last;
cur = last=0;
i = -1;
_cputs("string & enter: \n\n");
while ((x = getch()) != 0x0d) { // 0x0d == "\n"
bf[(i+=1)] = x;
if (x == '1') cur++; // 0x31 == 1
else if (cur) {
if (!last || last > cur) last= cur;
cur = 0;
}
putch(x);
}
if (cur && last > cur) last= cur;
bf[(i+=1)] = 0x00; //êîíåö ñòðîêè
_cputs("\nminimum -- ");
_cprintf("%i", last);
_cputs(" characters\nstring -- ");
_cputs(bf);
getch();
return 0;
} |
но только это не c++, это с | |
|
|
|
|
|
|
|
для: exp
(20.12.2008 в 19:15)
| | А на с++ как сделать ?
Заочникам тяжеловато самим осваивать... тем более если никогда раньше с С++ не общался !
Можешь помочь ? | |
|
|
|
|
|
|
|
для: WveB
(20.12.2008 в 19:31)
| | Я и сам только только начал пытаться понять ;) вот из книги
C++ - универсальный язык программирования, задуманный так, чтобы сделать программирование более приятным для серьезного программиста. За исключением второстепенных деталей C++ является надмножеством языка программирования C. Помимо возможностей, которые дает C, C++ предоставляет гибкие и эффективные средства определения новых типов.
И далее там что-то о классах и структурах и ... OOP вобщем , пока лично заметил только отличия в синтаксисе написания struct в С и struct в С++, компилятор C не понимал то что для C++.
И много примеров на английском , с использованием классов для упрощения работы со строкой , и всяких модулей типа MFC . Вроде обьясняют что как-то разумнее используется памть в этих классах.
Здесь в этой теме сам видишь как я попытался создать два класса , только чтобы попробовать удобнее получать длинну строки.) пока бросил такое желание , ещё многое надо читать, потом буду опять пробовать :)
но то что работает в C должно всётаки работать в C++, другое дело требуется-ли от вас объектно-ориентированный подход к решению задачи | |
|
|
|
|
|
|
|
для: exp
(20.12.2008 в 20:08)
| | проще говоря ты не знаешь как это сделать ?
Как же ты тогда предъидущюю задачу сделал, которую M@M@ZOGLO не мог сделать ? | |
|
|
|
|
 14.1 Кб |
|
|
для: WveB
(20.12.2008 в 20:37)
| | Вы компилировали и запускали этот последний код ?
(прикрепил exe-файл)
тогда вы должны понять что я ничего не понял из задачки :)
то что группы цифр разделены пробелом , я понял
но посчитать колличество едениц можно и в такой строке 000 111 00 11
можно в такой 0101 1010 1100 100
поэтому я просто считал подряд-идущие еденицы не обращая внимания на любой другой ввод с консоли,
хотя там и правда нет действий над строкой как над массивом
А в предыдущей задачке оказалось что использовалась ещё и строка введённая с консоли
и та задачка решилась совершенно случайно и самопроизвольно тоже на чистом C,пока я решал свои задачки . Я и не знал , что такое решение могло пригодиться вообще :)
Могу сделать на C используя прогон статической строки в цикле, но опять-же 0000 111 или 0101 110 ?
и OOP пока не трогаю , потомучто не знаю | |
|
|
|
|
|
|
|
для: exp
(20.12.2008 в 21:27)
| | строка идет произвольная, то есть 010110 01101110 110 000 11001
как-то так !
Надо чтоб находилась самая короткая группа и в ней надо посчитать сколько единиц в ней ! | |
|
|
|
|
 1.4 Кб |
|
|
для: WveB
(20.12.2008 в 21:31)
| | попробовал тут сделать что-то похожее на C++
и не смог найти как-же при помощи cin получить строку вместе с пробелами :)
вроде всё правильно должно считать с локальной строкой , но почему при вводе новой строки не помещает текст после пробелов?
подскажите есть-ли возможность с помощью cin ввести строку полностью ?
разобрался вроде
здесь есть баг если всего одна группа и ограничения 512
//upd:
прикрепил этот старый код | |
|
|
|
|
|
|
|
для: exp
(21.12.2008 в 00:31)
| | спасибо что не отказал, но на С++ не работает это, надо компилировать ! | |
|
|
|
|
|
|
|
для: WveB
(21.12.2008 в 01:53)
| | вот такой вариант вроде получше
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
char str[512] = "01110001 1110110 0000001110000 0100100101\0";
char x;
int i, group=0, a=0, ln=0, ones[2];
/*
ones[2]- первый элемент длинна группы из ln
второй колличество едениц из a
group - только 0 или 1 или 2
*/
cout << "enter digit:"<< endl;
cout << " 1 new string"<< endl;
cout << " 2 default string:"<< endl;
cout << " '"<< str <<"'"<< endl; // если лениво вводить строку
cout << " 0 exit"<< endl;
cin >> i;
cout << endl;
switch(i) {
case 1:
cout << "(Notice: only ' ', 1, 0 characters)"
<<endl<<"enter string:"<< endl;
cout.flush();
cin.getline(&x, 1); // лишний cin думаю баг devCpp
cin.getline(str,511);
break;
case 2:
break;
default:
i = 0;
}// end of switch
if (i) {
i=0;
for (i=0; (x = str[i]) != 0x00; i++) {
switch (x) {
case '1':
ln++;
a++;
group=2;
break;
case '0':
ln++;
group=2;
break;
default:
if (group>1 && (!ones[0] || ones[0]>ln)) {
ones[0] = ln;
ones[1] = a;
}
group = (group)? 1: 0;
ln = a = 0;
}// end of switch
}// end of while
if (group>1 && (!ones[0] || ones[0]>ln)) {
ones[0] = ln;
ones[1] = a;
} // последнее возможное нахождение
cout <<endl<<"result: "<< ones[1]<< endl;
cout <<"length group = "<< ones[0]<< endl;
cout <<"string = "<< str << endl;
}
// system("PAUSE");
cin.getline(&x, 1); // // лишний cin думаю баг devCpp
cin.getline(&x, 1); // типа getch();
return 0;
} |
какие ошибки выдаёт ? | |
|
|
|
|
|
|
|
для: exp
(21.12.2008 в 03:43)
| | Ошибки такие :
massiv.CPP(2,16):namespace name expected
massiv.CPP(77,2):Parameter 'argv' is never used
Вот такие вот ошибки | |
|
|
|
|
|
|
|
для: WveB
(21.12.2008 в 21:24)
| | похоже на Borland C++BuilderX
попробуйте просто заменить
int main(int argc, char *argv[])
таким
int main()
просто жаловалось на то что эти переменные не разу не использовались
хотя наверное ещё лучше включить в начале файл
#include <stdlib.h>
и раскомментировать в конце
system("PAUSE");
удалив эти два вызова cin.getline(&x, 1); // // лишний cin думаю баг devCpp
cin.getline(&x, 1); // типа getch()
//PS
два cin.getline оказалось и в C++BuilderX так-же как в devCpp
думаю баг Виндовс :)) | |
|
|
|
|
|
|
|
для: exp
(21.12.2008 в 21:58)
| | ругается вот на эту строчку
namespace std; | |
|
|
|