Получение размера аргументов командной строки/доступ к отдельным символам в аргументах командной строки

Заранее спасибо за то, что прочитали это,

Я тренируюсь получать и обрабатывать аргументы из командной строки, пишу программу, которая принимает один аргумент и возвращает его размер. Из того, что я прочитал, каждый аргумент командной строки завершается нулем, и к каждому отдельному символу можно получить доступ как к обычному 2D-массиву (пожалуйста, поправьте меня, если я ошибаюсь). Поэтому я написал:

for (int i = 0; i > -1; i++)
{
    cout << "Doing " << &argv[1][i] << endl;
    if (&argv[1][i] != "\0") Size++;
    else break;
}

Это прекрасно компилируется под g++, но когда я запускаю его, происходит следующее:

user@computer:~/Programming$ ./ReturnSize 12345
Doing 12345
Doing 2345
Doing 345
Doing 45
Doing 5
Doing 
Doing ORBIT_SOCKETDIR=/tmp/orbit-user

И так продолжается до тех пор, пока не произойдет segfaults. Что я делаю не так? Есть ли лучший способ определения размера аргументов/доступа к отдельным элементам в аргументах?


person errorc2146    schedule 12.03.2014    source источник
comment
почему бы не использовать strlen(char*)?   -  person pippin1289    schedule 13.03.2014


Ответы (5)


В этом заявлении

if (&argv[1][i] != "\0") Size++;

вы сравниваете два указателя (строковый литерал неявно преобразуется в указатель на его первый элемент в этом выражении). Поскольку они занимают разные области памяти, условие в операторе if всегда будет равно true, если массивы не будут перекрывать друг друга.

Измените это утверждение на

if ( argv[1][i] != '\0' ) Size++;

Чтобы получить размер аргумента командной строки, вы можете использовать стандартную функцию C std::strlen, объявленную в заголовке <cstring>.

Например

size_t Size = std::strlen( argv[1] );

Что касается вашего цикла, то его можно было бы написать проще

size_t Size = 0;
while( argv[1][Size] )
{
    cout << "Doing " << &argv[1][Size] << endl;
    ++Size;
}
person Vlad from Moscow    schedule 12.03.2014

for (int i = 0; i > -1; i++) действительно ??? Простой способ ::

#include<iostream>
#include<cstdlib>
int main(int argc, char* argv[])
{
    for (int i = 1; i < argc; ++i)
    {
        std::string temp = argv[i];
        std::cout << temp << " | " << temp.length() << std::endl;
        Size = temp.length();
    } 
    return 0;
}
person DOOM    schedule 12.03.2014
comment
Довольно хороший ответ, но что такое размер? Что должна делать эта последняя строка в цикле? - person shawn1874; 14.03.2014

Помимо того, что вся программа немного странная (см. комментарий pippin1289), ваше условие if неверно: вы хотите:

if (argv[1][i] != '\0')
person user3392484    schedule 12.03.2014

Цикл for не имеет смысла. Вы увеличиваете i и проверяете, больше ли оно, чем -1. Конечно, это является. Проверка строки "\0" отличается от проверки нулевого символа "\0". Это один из источников вашей беды. Кроме того, я бы не стал зацикливать символ за персонажем в первую очередь. Вы можете просто отправить всю строку в поток или использовать для нее функции библиотеки C.

person shawn1874    schedule 12.03.2014

Любое логическое выражение может быть оценено. Например, вы можете написать:

for (int i = 0; true; i++) {
}

При этом что-то вроде

for (int i = 0; i argv[1][i] != '\0'; i++) {

}

может работать, хотя и нетрадиционно

person Dillon    schedule 24.04.2016