PDA

Показать полную графическую версию : Строки, массивы строк...


ManHack
18-04-2010, 15:21
Каким образом в С работать со строками? (не массивами из символов)
Там вроде есть какой-то ньюанс, в отличие от Java, эти конструкции не очень-то работают:
String name = "********";
String[] name = new String [namesCnt];
Как же всё-таки создать переменную типа String в C? Массив из переменных типа String?

ganselo
18-04-2010, 15:50
Каким образом в С работать со строками? (не массивами из символов) »
Если в C, то только с массивом символов.
Если в C++, то подключаем заголовочный #include <string> и работаем.

#include <iostream>
#include <string>
using namepsace std;
int main()
{
string str = "blablabla";
string *str2 = new string[100]; //сто строк
str2[0] = "str0";
str2[1] = "str1";
....
delete [] str2;
}

ManHack
18-04-2010, 16:05
Ясно, спасибо... как тогда будет выглядеть объявление массива из массивов из символов в Cи? :)
А каким образом можно сравнивать массивы из символов? (аналогично String.compareTo() в Java)

ganselo
18-04-2010, 16:45
как тогда будет выглядеть объявление массива из массивов из символов в Cи? »

char str_array[100][1024]; //сто строк длиной 1024


А каким образом можно сравнивать массивы из символов? »
Есть функция int strcmp(const char *str1, const char *str2); (из string.h). Возвращает 0 если строки одинаковые, -1 если первая меньше, 1 если первая больше.

if(strcmp("str1", "str1") == 0) printf("Одинаковые");

pva
18-04-2010, 17:45
что понимается под массивом из String? в c/с++ нет класса String. Строки в С, а по наследству и в С++ представляются массивом сз элементов типа char или wchar_t, но в стандартной библиотеке C++, в пространстве имён std есть класс string, который удовлетворяет большинство потребностей в строках. Можно придумать свой класс String, работающий по собственным правилам (например это сделал borland, объявив классы AnsiString и WideString), но это излишне, если допускается использование std::string.
Теперь о массиве. Вообще конструкция

#include <string>
using namespace std;
...
string str_array[100];

допустима, но в стандартной библиотеке есть контейнер vector, позволяющий хранить объекты в виде массива и контейнер list, позволяющий хранить объекты в 2-связном списке. Таким образом, в зависимости от задумки автора, можно поступит двояко:
Код:
String name = "********";
String[] name = new String [namesCnt]; »

// случайный доступ к элементам
vector<string> str_arr1(str_num); // str_num пустых строк
vector<string> str_arr2(str_num, string("********")); // str_num строк, инициализированных в "********"

// только последовательный доступ
list<string> str_list0; // пустой список строк
list<string> str_list1(str_num); // str_num пустых строк
list<string> str_list2(str_num, string("********")); // str_num строк, инициализированных в "********"

Кроме того, в зависимости от задачи, можно использовать и другие контейнеры.
Для сравнения строк переопределён оператор==(string const&, string const&), для сравнения контейнеров то же самое сделано для контейнеров. То есть:

clog << (str_arr1==str_arr2 ? "Векторы равны" : "Есть различия") << endl;


Теперь по поводу C: Далее буду считать, что автор темы отличает C от C++.
Управление хранилищем полностью отводится на откуп прогаммиста. Поэтому надо заранее позаботиться о выделении и уничтожении памяти. Класса String в C нет. Вместо этого есть массив из char, в конце которого символ с кодом 0. Для сравнения строк функции strcmp, strcmpi или любая самописная, которая сравнивает поэлементно до тех пор, пока не встретит код 0. Сравнение массивов только самописное или не из стандартной библиотеки C.

otkryto
27-04-2011, 18:36
Здравствуйте!
Скажите пожалуйста как на обычном Си реализовать такое
В соревнованиях по прыжкам в длину принимают участие 10 спортсменов. Считая заданным список фамилий
спортсменов и их результаты в порядке стартовых номеров, получить итоговую таблицу, в которой содержатся
фамилии и результаты в порядке занятых мест.
не пойму как массивы строку работают, вылезает ошибка Null pointer assignment либо просто закрывается окно

#include <stdio.h> #include <iostream.h> #include <iomanip.h> #include <string.h>
main()
{
int r[10];
char *m[10];
int i,j,n;
char *s;
for(i=0; i<=9; i++)
{
cout<<"Vvedite familijy uchastnika";
cin>>m[i];
cout<<"Vvedite rezultat uchastnika"<<endl;
cin>>r[i]; } cout<<endl<<endl;

printf("Vveden \n");
for(i=0; i<=9; i++)
{
cout<<m[i]<<" ";
cout<<r[i]<<" "<<endl;
}

printf("\n");
printf("\n");

for(i=0; i<=8; i++)
{
for(j=i; j<=9; j++)
{
if (r[i]<r[j])
{
n=r[j];
r[j]=r[i];
r[i]=n;

s=m[j];
m[j]=m[i];
m[i]=s;
}
}
}
printf("Otvet \n");
cout <<endl;
for(i=0; i<=9; i++)
{
cout<<m[i]<<" ";
cout<<r[i]<<" "<<endl;
} return 0; }

El Scorpio
29-04-2011, 06:31
не пойму как массивы строку работают, вылезает ошибка Null pointer assignment либо просто закрывается окно »
Объясняю. char* - это не "массив строк", а указатель на объект типа "символ" (число, означающее код символа). Просто по правилам языка С указатель на начальный объект массива одновременно является указателем на сам массив (со смещением в 0 байт).


// в коде программы
const char *Stroka = "Hello Word";
// в отладчике
Значение Stroka будет равна "Hello Word\0"
Значения *Stroka и Stoka[0] будут равны 'H'
Значения *(Stroka+1) и Stroka[1] будут равны 'e'


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

В С нет объекта "строка" - есть "массив символов, оканчивающийся нулём" (символом с кодом "ноль"), который компилятором и отладчиком обрабатывается особым образом, создавая over 9000 проблем любому начинающему программисту.
У меня сейчас нет времени полноценную лекцию по данной теме писать, ибо она слишком большая и сложная. Придётся послать вас в гугль :(




© OSzone.net 2001-2012