Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313

Возможно ли без использования цикла получить символ с конца нулевого аргумента main()?

01.08.2016, 19:47. Показов 2459. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Использую имя файла как аргумент для предварительной настройки программы. Хочу без помощи поиска в цикле получить пред-пред-пред последний символ нулевого аргумента, то есть что-то до ".exe".

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

Однако, sizeof(argv[0]) говорит, что у меня 4 байта занимает этот аргумент, хотя там "C:\\Projects\\Debug\\XO5.exe".
И как такая символьная char-строка может занимать 4 байта, если sizeof(char) == 1?

Объясните, пожалуйста, где я ошибаюсь.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.08.2016, 19:47
Ответы с готовыми решениями:

Как получить символ клавиатуры без использования TextBox
Добрый день, всем! Уже пару дней борюсь с одной проблемой: Есть класс унаследованный от System.Windows.Controls.Control и все,...

Возможно ли получить от сервера простой ответ без использования data.store?
В общем, нужна просто проверка на существование поля с данными. Т.е. нужно что: Есть таблица с адресными данными по предприятиям. Есть...

Организация цикла без использования оператора цикла
Вычислить значение функции:F=система из 3-х уравнений...1 ур-ие:2*a*Y, при Y>0..2 ур-ие:0,3*10^1.5*(a*sinY/1+a^2), при Y<=-2..третье...

19
 Аватар для HenryDukart
125 / 125 / 44
Регистрация: 05.10.2013
Сообщений: 462
01.08.2016, 19:51
Lyosha12, если мы говорим про

C++
1
int main(int argc, char *argv[])
то argv - массив указателей(!!) на тип char. Видимо, ваша операционная система 32-х разрядная, поэтому в ней все указатели имеют размер 4 байта (независимо на то, на что они указывают). В этом массиве находятся указатели(!!) на последовательности символов, заканчивающихся символом '\0'.

Длину строки вы можете узнать только с помощью цикла или стандартных функций.
0
2688 / 2260 / 244
Регистрация: 03.07.2012
Сообщений: 8,231
Записей в блоге: 1
01.08.2016, 19:51
sizeof(argv[0]) - это указатель на символьную строку. В 32-битной архитектуре все указатели занимают 4 байта.
О как совпало
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
01.08.2016, 19:55
Лучший ответ Сообщение было отмечено gru74ik как решение

Решение

Цитата Сообщение от Lyosha12 Посмотреть сообщение
Хочу без помощи поиска в цикле получить пред-пред-пред последний символ нулевого аргумента, то есть что-то до ".exe".
Если нужно имя файла и доступен boost, то лучше так
C++
1
2
3
boost::filesystem::path p("c:/dir/dir/file.ext");
std::cout << "filename and extension : " << p.filename() << std::endl; // file.ext
std::cout << "filename only          : " << p.stem() << std::endl;     // file
1
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313
01.08.2016, 21:04  [ТС]
Цитата Сообщение от HenryDukart Посмотреть сообщение
В этом массиве находятся указатели(!!) на последовательности символов, заканчивающихся символом '\0'.
argv[0] в моём случае можно представить как test[1][26]. [25 + \0] = [26], test[25] == "\0", test[23] == 'x'.
Если узнать размер статического, то это sizeof(test) == 26. Тут всё как я и думал.
Но, узнавая размер динамического тем же макаром, я получаю 4. Получается, это размер массива, в котором находятся указатели? Но указатели занимают 4 байта (хотя у меня и винда, и CLion, и компилятор x64), как и тип char. Как так?

И, если argv - массив указателей, то argv[0] - указатель на первый char-массив. Следовательно, должно выполняться тождество sizeof(argv[0]) == sizeof(test), но это не так, ибо argv[0] - это указатель, занимающий 4 байта... Тогда для получения размера массива, в котором хранятся символы нулевого, аргумента я должен сделать так: sizeof(*argv[0]). Верно? Нет, ибо выдаёт 1 - размер одного символа типа char. То есть, это аналогично sizeof(argv[0][0])... Так как же получить этот размер массива нулевого аргумента?? Вот тут у меня не стыковка в понимании...

Добавлено через 38 секунд
Цитата Сообщение от Kastaneda Посмотреть сообщение
Если нужно имя файла и доступен boost, то лучше так
Спасибо, как будет время, попробую этот способ. Но сначала разберусь с размером первого аргумента динамического массива...

Добавлено через 11 минут
Хм... Получается, что массив, в котором содержатся указатели на аргументы, занимает 4 байта, ибо аргумент всего один - нулевой... Нет, это не верно - всё равно получаю 4 байта при двух аргументах. И при трёх...
0
1617 / 1182 / 553
Регистрация: 08.01.2012
Сообщений: 4,561
01.08.2016, 21:11
в #5 слишком много слов, не все понял, strlen отменили?
sizeof(массив) если он не статический возвращает 4
1
829 / 253 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
01.08.2016, 21:14
Нечто древневелосипедное:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
#include <vector>
#include <string>
 
int main(int argc, char **argv)
{
    std::vector<std::string> params(argv, argv+argc);//Все параметры в векторе
    std::string name;
    if(!params.empty())
    {
        std::string &param = params.front();
        std::string::size_type dotPos = param.find_last_of(".\\\/");
        if(dotPos == std::string::npos)
        {
            name = param;
        }
        else{
            if(param[dotPos] == '\\' || param[dotPos] == '\/')
            {
                name = param.substr(dotPos+1);
            }
            else
            {
                std::string::size_type slPos = param.find_last_of("\\\/", dotPos);
                if(slPos == std::string::npos)
                {
                    name = param.substr(0, dotPos);
                }
                else
                {
                    name = param.substr(slPos+1, dotPos-slPos-1);
                }
            }
        }
    }
    std::cout << "name: " << name << std::endl;
}
1
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313
02.08.2016, 04:57  [ТС]
Цитата Сообщение от MansMI Посмотреть сообщение
strlen отменили?
Нет, но длина строки - как раз поиск LT, чего я использовать сразу не хотел.
Цитата Сообщение от HelicopterK52 Посмотреть сообщение
Нечто древневелосипедное:
Как я понял из тем за 2012 год, динамический массив я делал в стиле C. В C++, как Вы и написали, для таких целей служит класс vector. И в C нет возможности узнать отведённую память под динамический массив через new, а vector предоставит такую возможность. Спасибо, теперь черёд копать эту особенность.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
02.08.2016, 08:54
Лучший ответ Сообщение было отмечено Lyosha12 как решение

Решение

Цитата Сообщение от Lyosha12 Посмотреть сообщение
Так как же получить этот размер массива нулевого аргумента?? Вот тут у меня не стыковка в понимании...
Просканировать все символы массива, на который указывает указатель нулевого аргумента, в поисках нуль-символа. Это делает функция strlen. Подругому здесь не получится.

Еще нужно понимать, что sizeof - это операция времени компиляции и основывается она на статическом типе своего аргумента.
Когда ты объявляешь
C++
1
char buf[10];
то тип buf - char[10], при передаче в функцию массив преобразуется в указатель char *, информация об исходном типе теряется. Следовательно мы уже не можем на нее рассчитывать при оценке размера массива с помощью sizeof: тип "указатель на char" не содержит сведений о размере того, на что он указывает. Если размер не передается вторым аргументом, то можно рассчитывать только на strlen (и подобное), да и то только в том случае, если передается С-строка, а не просто набор байт.

Очень важно делать различия между массивами и указателями, многие пренебрегают этим, а потом начинаются вот такие проблемы с пониманием. Типизация - это краеугольный камень С++, программу надо оценивать как с точки зрения статической информации (известной на этапе компиляции), так и с точки зрения этапа исполнения, с пониманием того что остается в программе, когда она уже скомпилирована.
1
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313
02.08.2016, 09:00  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Сообщение от Lyosha12
Так как же получить этот размер массива нулевого аргумента?? Вот тут у меня не стыковка в понимании...
Просканировать все символы массива, на который указывает указатель нулевого аргумента, в поисках нуль-символа. Это делает функция strlen. Подругому здесь не получится.
Еще нужно понимать, что sizeof - это операция времени компиляции и основывается она на статическом типе своего аргумента.
Когда ты объявляешь
C++Выделить код
1
char buf[10];
то тип buf - char[10], при передаче в функцию массив преобразуется в указатель char *, информация об исходном типе теряется. Следовательно мы уже не можем на нее рассчитывать при оценке размера массива с помощью sizeof: тип "указатель на char" не содержит сведений о размере того, на что он указывает. Если размер не передается вторым аргументом, то можно рассчитывать только на strlen (и подобное), да и то только в том случае, если передается С-строка, а не просто набор байт.
Очень важно делать различия между массивами и указателями, многие пренебрегают этим, а потом начинаются вот такие проблемы с пониманием. Типизация - это краеугольный камень С++, программу надо оценивать как с точки зрения статической информации (известной на этапе компиляции), так и с точки зрения этапа исполнения, с пониманием того что остается в программе, когда она уже скомпилирована.
Идеальный ответ. Я только позавчера начал изучать вплотную указатели и динамические массивы. Думал, что принцип понял, но Вы ещё добавили толику понимания. Спасибо
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
02.08.2016, 09:08
Цитата Сообщение от Lyosha12 Посмотреть сообщение
и динамические массивы
Вот с этим как раз и связаны основные ошибки.
В c++ нет динамических массивов.
В этом вся проблема в понимании массива как типа.
Есть структура данных - массив, а есть тип данных - массив.
Вот такого типа как динамический массив в языке нет,
но структуру данных в виде динамического массива реализовать можно.

Под динамическим я здесь подразумеваю расширяемый массив,
а не имеющий динамические время хранения,
что тоже вносит некоторую толику запутанности.
1
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313
02.08.2016, 11:41  [ТС]
Цитата Сообщение от Croessmah Посмотреть сообщение
Есть структура данных - массив, а есть тип данных - массив.
Запомню.
Цитата Сообщение от Croessmah Посмотреть сообщение
Под динамическим я здесь подразумеваю расширяемый массив,
а не имеющий динамические время хранения,
что тоже вносит некоторую толику запутанности.
Интересно, какого мнения мой преподаватель...

Но как тогда мне называть "не-динамический-временный" массив?
Спасибо
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
02.08.2016, 11:42
Цитата Сообщение от Lyosha12 Посмотреть сообщение
не-динамический-временный
Это что такое? Примерчик кодом можно?

Добавлено через 28 секунд
Цитата Сообщение от Lyosha12 Посмотреть сообщение
Интересно, какого мнения мой преподаватель...
Скорее всего такого, которое написано в методичке.
0
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313
02.08.2016, 11:46  [ТС]
Хотя, подождите, Вы не противоречите сами себе?
Цитата Сообщение от Croessmah Посмотреть сообщение
В c++ нет динамических массивов.
Цитата Сообщение от Croessmah Посмотреть сообщение
Под динамическим я здесь подразумеваю расширяемый массив,
Цитата Сообщение от Croessmah Посмотреть сообщение
структуру данных в виде динамического массива реализовать можно.
Добавлено через 1 минуту
Цитата Сообщение от Croessmah Посмотреть сообщение
Это что такое? Примерчик кодом можно?
Просто переосмыслил Вашу фразу
Цитата Сообщение от Croessmah Посмотреть сообщение
динамические время хранения
0
Неэпический
 Аватар для Croessmah
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 1
02.08.2016, 11:59
Цитата Сообщение от Lyosha12 Посмотреть сообщение
Вы не противоречите сами себе?
Нет. Просто Вы не то процитировали.
Цитата Сообщение от Croessmah Посмотреть сообщение
Вот такого типа как динамический массив в языке нет
Цитата Сообщение от Croessmah Посмотреть сообщение
но структуру данных в виде динамического массива реализовать можно
а-ля std::vector

Добавлено через 3 минуты
Цитата Сообщение от Lyosha12 Посмотреть сообщение
Просто переосмыслил Вашу фразу
Почитайте на тему storage duration.
А именно
automatic storage duration - автоматическое время хранения (живет до конца области видимости)
static storage duration - статическое время хранения (живет всё время выполнения программы, ну, почти всё)
dynamic storage duration - динамическое время хранения (живет столько, сколько позволит программист)
thread storage duration - потоковое время хранения (живет до завершения потока)
1
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313
02.08.2016, 12:10  [ТС]
Цитата Сообщение от Croessmah Посмотреть сообщение
а-ля std::vector
Понял, поставил на повестку дня.
Цитата Сообщение от Croessmah Посмотреть сообщение
Почитайте на тему storage duration.
А именно
automatic storage duration - автоматическое время хранения (живет до конца области видимости)
static storage duration - статическое время хранения (живет всё время выполнения программы, ну, почти всё)
dynamic storage duration - динамическое время хранения (живет столько, сколько позволит программист)
thread storage duration - потоковое время хранения (живет до завершения потока)
Ну, временный массив, наверно, более обобщённое понятие этих четырёх вариантов. Действительно криво выразился. Спасибо, что поправляете
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
02.08.2016, 13:34
Цитата Сообщение от Lyosha12 Посмотреть сообщение
Ну, временный массив, наверно, более обобщённое понятие этих четырёх вариантов.
Вообще говоря, временный массив (если подразумевать понятие array prvalue) - это частный случай первого варианта.
Пример, для тех, кому интересно что это за зверь - array prvalue

C++
1
2
3
4
5
6
7
8
9
int main()
{
    using array_type = int[10];
 
    array_type{1,2,3}; // returns array prvalue
 
    array_type && rv = array_type{1,2,3,4}; // bind to rvalue reference
    array_type const & cr = array_type{}; // bind to const reference
}
1
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313
02.08.2016, 14:16  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Вообще говоря, временный массив (если подразумевать понятие array prvalue) - это частный случай первого варианта.
Для меня это пока что инопланетные строчки
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
02.08.2016, 14:38
Цитата Сообщение от Lyosha12 Посмотреть сообщение
Для меня это пока что инопланетные строчки
Начать с изучения того, что вообще такое "временный объект".
0
 Аватар для Lyosha12
41 / 41 / 11
Регистрация: 02.04.2016
Сообщений: 313
02.08.2016, 14:42  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Начать с изучения того, что вообще такое "временный объект".
Спасибо. Обязательно покопаю, когда будет нужна или когда делать нечего будет.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
02.08.2016, 14:42
Помогаю со студенческими работами здесь

gtk_entry_get_text - не хочет отдавать текст без остановки main цикла
суть проблемы - у меня есть main функция, которая создаёт одно окно и параллельно запускает функцию, которая создаёт второе окно. На втором...

Шейкерная сортировка без использования while цикла
Ребят, сделал шейкерную сортировку через два вложенных цикла - не работает. Не могу понять в чем проблема, подскажите пожалуйста. ...

Преобразовать код без использования цикла
Как выполнить такое преобразование без использования цикла? С применение функций или рекурсии. A = B = for i in...

Вычислить факториал без использования цикла
Напишите программу вычисления факториала без применения операторов цикла. (использовать условный оператор и оператор безусловного перехода).

Переписать код без использования цикла
Sub ex3() Dim sNum As String, i As Integer, j As Integer, otvet As Boolean sNum = InputBox(&quot;Введите число:&quot;) For i = 1 To...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru