используя строки как указатель на свой первый символ - PullRequest
0 голосов
/ 08 апреля 2011
int main()  
{
    char name[]="avinash";   
    const char* nameano="a";   
    strtok(name,"n");   
    cout<<"the size of name is"<< sizeof(name);   
    cout<< name;
} 

strtok принимает аргументы (char*, const char*); name - это массив, и, следовательно, указатель на его первый элемент. Но если мы сделаем объявление вроде

string name="avinash";

и передайте name в качестве первого аргумента strtok, тогда программа не будет работать, но она должна, потому что name, строка, является указателем на свой первый символ.

Также, если мы напишем

const string n = "n";

и передать его как второй аргумент, он не работает; это была моя первая проблема.

Теперь также вывод sizeof(name) равен 8, но это должно быть 4, так как avinash был токенизирован. Почему это происходит?

Ответы [ 5 ]

4 голосов
/ 08 апреля 2011

Вы путаете несколько вещей.

strtok принимает аргументы (char *, const char *) .... name это массив и, следовательно, указатель на его первый элемент ...

name - это массив, а - это не указатель на его первый элемент. Массив распадается в указателе на свой первый аргумент в нескольких контекстах, но в принципе это совершенно другая вещь. Вы замечаете это, например когда вы применяете оператор sizeof к указателю и к массиву: для массива вы получаете размер массива (т.е. совокупный размер его элементов), для указателя вы получаете размер указателя (который является фиксированным).

но если мы сделали объявление вроде string name = "avinash" и передали name в качестве аргумента тогда прога не работает, но должна, потому что имя строки является указателем на ее первый символ ...

Если вы сделаете декларацию типа

string name="avinash";

вы говорите совершенно другое; string здесь не C-строка (то есть char[]), а тип C ++ std::string, который является классом, который управляет динамической строкой; эти две вещи совершенно разные.

Если вы хотите получить постоянную C-строку (const char *) из std::string, вам нужно использовать метод c_str(). Тем не менее, вы не можете использовать указатель, полученный таким образом с strtok, так как c_str() возвращает указатель на C-строку const, то есть она не может быть изменена. Обратите внимание, что strtok не предназначен для работы со строками C ++, поскольку он является частью устаревшей библиотеки C.

также, если мы напишем const string n = "n"; и передать его в качестве второго аргумента, он не работает ... это была моя первая проблема ...

Это не работает для точно такой же мотивации, но в этом случае вы можете просто использовать метод c_str(), поскольку второй аргумент strtok - это const char *.

теперь также размер вывода (name) равен 8, но это должно быть 4, поскольку avinash был токенизирован.

sizeof возвращает «статический» размер своего операнда (т. Е. Сколько памяти выделено для него), он ничего не знает о содержимом name. Чтобы получить длину C-строки, вы должны использовать функцию strlen; для C ++ std::string просто используйте метод size().

0 голосов
/ 08 апреля 2011

Как вы сказали, strtok принимает аргументы типа char * и const char *.string не является char *, поэтому передача его в качестве первого аргумента не будет компилироваться.Для второго аргумента вы можете преобразовать строку в const char *, используя функцию-член c_str().

Какую проблему вы пытаетесь решить?Если вы просто пытаетесь узнать, как работает strtok, было бы намного лучше придерживаться необработанных массивов символов.Эта функция унаследована от C и, следовательно, не была разработана с учетом строк C ++.

0 голосов
/ 08 апреля 2011

Прежде всего, strtok - это C, а не C ++, и не предназначен для работы со строками C ++.Кроме того, он не может работать, если вы не используете возвращаемый результат функции.

char name[]="avinash";   
char * tok_name = strtok(name,"n");   
std::cout<<"the size of name is"<< sizeof(tok_name);   
std::cout<< tok_name;

Вам следует рассмотреть возможность использования std::string::find, std::string::substr и других элементов из библиотеки STL вместо функций C.

0 голосов
/ 08 апреля 2011

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

int main()
{
   char name[] = "avinash";
   const char* nameano = "a";
   char* token;
   token = strtok(name, "n"); 
   cout << "the length of the TOKEN is" << strlen(token) << endl;
   cout << token << endl;
   cout << "the length of the string is" << strlen(name) << endl;
   cout << name << endl;
}

Попробуйте, может быть, это?Я не перед компилятором, поэтому, скорее всего, я допустил ошибку, но он должен помочь вам решить эту проблему.

Это также может помочь: http://msdn.microsoft.com/en-us/library/2c8d19sb(v=vs.71).aspx

0 голосов
/ 08 апреля 2011

Я думаю, вы должны передать свой массив имен [] в strtok следующим образом:

strtok(&name[0],"n");  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...