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

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

01.08.2016, 19:47. Показов 2390. Ответов 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
1615 / 1181 / 552
Регистрация: 08.01.2012
Сообщений: 4,558
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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 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
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 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
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
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
Ответ Создать тему
Новые блоги и статьи
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка. Рецензия / Мнение Это мой обзор планшета X220 с точки зрения школьника. Недавно я решила попытаться уменьшить свой. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru