Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Не получается создать массив по размеру другого...


Автор: Вп 16.8.2005, 10:43
Доброе время суток. Возникла проблема. Мне необходимо (в учебных целях) написать функцию, которая бы получала в качестве аргументов строку (char-массив), и переворачивала ее.
Попробовал вот так:
Код

void rev(char s[])
{
    char ch='\0';
    //const int i=strlen(s)+1;    //не работает!
    const int i=sizeof(s);
    char s2[i];
    for (int count1=i, count2=0; count1>=0; count1--, count2++)
//дальше пока неинтересно….
}

Столкнулся с трудностями уже на момент инициализации переменных. Как видно из примера, я хотел создать временный массив s2, равный по размеру массиву-аргументу s, и посимвольно скопировать в него в обратном порядке содержимое массива-аргумента.
Проблема в том, что компилятор ругается, если я пытаюсь определить размер временного массива через закоментированную строчку, а sizeof (s) возвращает неправильный результат: например, если передается строка "as458", sizeof(s) возвращает результат 4, хотя, если я все правильно понимаю, каждый char-элемент массива занимает один байт, следовательно, размер массива должен быть шесть байт (включая завершающий нуль-символ).


Автор: chaos 16.8.2005, 10:55
делай не sizeof а strlen

Автор: Hroft 16.8.2005, 10:57
Все правильно сайзоф тебе говорит. 4 - это размер указателя на char, коим является твой формальный аргумент. Тебе придется либо использовать класс std::string, либо передавать также и размер в еще одном аргументе. Ну или самому определять размер, пробегаясь от первого символа, указатель на который есть, до символа конца строки. Но это не самый лучший вариант, по-моему.
Именно это и делает strlen, наверняка, про которую я забыл, а chaos напомнил.

Автор: Вп 16.8.2005, 11:00
Спасибо, разобрался! ФУнкция с 2-мя аргуменами - мой выбор smile)
Но все же, strlen дает правильный результат, но почему такой результат не получается вставить в обявление массива???

Автор: chaos 16.8.2005, 11:02
Цитата
Но все же, strlen дает правильный результат, но почему такой результат не получается вставить в обявление массива???

потомучто ты наверное его создаешь как-нибудь так
char mas[strlen(mas2)];
а надо
char *mas = new char[strlen(mas2)+1];
...
delete[] mas


одним словом так нельзя создавать массивы! Размер массива в статической памяти должен быть известен на этапе компиляции

Автор: Mayk 16.8.2005, 11:02
Цитата
void rev(char s[])
{
    char ch='\0';
    //const int i=strlen(s)-1;
    const int i=sizeof(s);
    char s2[i];
    for (int count1=i, count2=0; count1>=0; count1--, count2++)
//дальше пока неинтересно….
}

strlen(s)+1 вообще не принадлежит строке - бо это байт, следующий за 0, означающим конец строки.

Автор: Вп 16.8.2005, 11:19
Что-то обрадовался, а похоже рано...
Попытка вызова функции с 2-мя параметрами дает тот-же самый косяк, что и при попытке определить размер массива s2 через strlen:
Вот полный пример кода, который я пытался откомпилировать:
Код

#include <iostream>
using namespace std;


void mstold(char s[], int i2)
{
    char s2[i2];
}


void main()
{    

}


А вот сообщения компилятора:
C:\PROECT\LIPMAN\007\007.cpp(7) : error C2057: expected constant expression
C:\PROECT\LIPMAN\007\007.cpp(7) : error C2466: cannot allocate an array of constant size 0
C:\PROECT\LIPMAN\007\007.cpp(7) : error C2133: 's2' : unknown size
Error executing cl.exe.

Ругается на строку char s2[i2], считает синтаксис неверным, хотя я ее даже вызвать не пытаюсь, просто пока описал функцию.
Может, глаз замылился, и я не вижу очевидной ошибки?

Автор: Вп 16.8.2005, 11:22
Так, пока писал, пришло два ответа smile), chaos, твой последний пример содержит указатель, а мне принципиально надо работать с простым char-массивом. Получается, решения для простого массива нет smile((

Автор: Hroft 16.8.2005, 11:23
Тебе уже все написали.
Ты должен объявлять не статический массив, а динамический, поскольку на этапе компиляции неизвестен размер. Почитай пост chaos'а.

Автор: chaos 16.8.2005, 11:25
Цитата
Так, пока писал, пришло два ответа smile), chaos, твой последний пример содержит указатель, а мне принципиально надо работать с простым char-массивом. Получается, решения для простого массива нет smile((

не нравятся динамические массивы, делай заведомо БОЛЬШИЕ статические вот и все

типо:
#define MAXSTR 1024

Код

char mas[MAXSTR];
...

Автор: Hroft 16.8.2005, 11:25
Не понимаю, как это принципиально нужно работать со статическим массивом, но тогда используй массив размеров символов в 100, или сколько у тебя там максимум может понадобиться, и каждый раз оперируй только с его частью. Ты по задумке чтоли еще не можешь new пользовать?

Автор: Вп 16.8.2005, 11:26
Майк, если правильно понимаю, strlen возвращает размер строки в символах (то есть int число), а значит strlen()+1 - это всего лишь число символов строки+1...

Автор: chaos 16.8.2005, 11:27
Цитата
Майк, если правильно понимаю, strlen возвращает размер строки в символах (то есть int число), а значит strlen()+1 - это всего лишь число символов строки+1...

strlen возвращает кол-во символов без \0
пример
Код

char s = "12345";
printf ("%d\n", strlen(s)); //выведет 5


те получается если тебе надо скопировать строку в строку s2 она должна иметь размер strlen(s) + 1, те 5 байт для 12345 и один для \0

Автор: Mayk 16.8.2005, 11:52
Ну вот. chaos за меня уже ответил smile
единственное, что могу добавить -
обрати внимание на условие:
for (int count1=i, count2=0; count1>=0; count1--, count2++)
если использовать иное, нежели i=strlen(s)-1, то с таким условием будут глюки - так s[i] возвратит нуль, и(надо полагать, хотя кода нет) этот нуль запишется в самое начало второй строки => вторая строка будет сильно обрезана.
Кстати, можешь заместо new посмотреть alloca (он присутствует в старом bc3.1), память выделенная через него освободится автоматически при выходе из ф-ции.

Автор: Denn 16.8.2005, 12:26
STL используй. vector<> в данном случае.

Автор: Romikgy 16.8.2005, 13:10
Попробуй так :
Код

void rev(char *s)
{
    char ch='\0';
    //const int i=strlen(s)+1;    //не работает!
     int i=strlen(s);
     int i2=i>>1;
    //char s2[i];
    for (int j=0;j<(i2);j++)
    {
     ch=s[j];
     s[j]=s[i-1-j];
     s[i-1-j]=ch;
    }
        
//дальше пока неинтересно….
}

Автор: AtroX 18.8.2005, 10:52
Ну вы даете, переворачиваение строки делать с использованием дополнительной памяти - ГЛУПО!
Код

void Reverse(char* str)
{
   if (str == 0) return;

   int size = strlen(str);
   char temp;

   for (int i = 0; i < size / 2; i++) {
      temp = str[i];
      str[i] = str[size - i - 1];
      str[size - i - 1] = temp;
   }
}

Автор: AtroX 18.8.2005, 10:56
smile Не досмотрел, до 2ой страницы =)
А проверку на NULL сделать все же надо...
Т.к. в хелпе не написано возвращает ли strlen 0, если ему передается NULL.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)