Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: C++, strupr и указатели  (Прочитано 3731 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн [DarkNet]Alpha

  • Автор темы
  • Активист
  • *
  • Сообщений: 987
  • Эмоциональный эльдар
    • Просмотр профиля
    • EBM-радио
C++, strupr и указатели
« : 06 Октября 2010, 00:30:15 »
Внезапно оказалось, что в стандартной (не от микрософта) string.h нет функции strupr и подобных. Решил я написать расширение.
Вот порождение моего больного сознания:
void strupr(char *s){
    char *res=s;
    while(*res!='\0'){
        *s=toupper(*res);
        s++;
    }
}

#include <iostream>
#include <string.h>
#include "h/strex.h"
using namespace std;

int main()
{
    char *pstr1="ololowcase";
    strupr(pstr1);
    cout << *pstr1 << endl;
    return 0;
}
На выходе получаю ошибку сегментирования. ЧЯДНТ?

Оффлайн Kwah

  • Старожил
  • *
  • Сообщений: 1442
  • Ubuntu 17.10
    • Просмотр профиля
Re: C++, strupr и указатели
« Ответ #1 : 06 Октября 2010, 00:36:46 »
Забываешь cдвигать res?

Оффлайн [DarkNet]Alpha

  • Автор темы
  • Активист
  • *
  • Сообщений: 987
  • Эмоциональный эльдар
    • Просмотр профиля
    • EBM-радио
Re: C++, strupr и указатели
« Ответ #2 : 06 Октября 2010, 00:40:50 »
Всё равно ошибка сегментирования.

Пользователь решил продолжить мысль 06 Октября 2010, 00:43:41:
На статической строке сработало. Правда, я не понял, как...
« Последнее редактирование: 06 Октября 2010, 00:43:41 от [DarkNet]Alpha »

Оффлайн VestniK

  • Активист
  • *
  • Сообщений: 594
    • Просмотр профиля
Re: C++, strupr и указатели
« Ответ #3 : 06 Октября 2010, 00:47:19 »
Вот такой код выглядит куда логичней:
void strupr(char *s){
    char *ptr = s;
    while(*ptr != '\0'){
        *prt = toupper(*ptr);
        ptr++;
    }
}

З.Ы. сам не тестил

Пользователь решил продолжить мысль [time]Wed Oct  6 00:53:17 2010[/time]:
А почему бы не std::string использовать, там через итераторы сложней вылезти за пределы строки и получить сегфолт
std::string s;
for (std::string::iterator it = s.begin(); it != s.end(); it++) {
    *it = toupper(*it);
}
« Последнее редактирование: 06 Октября 2010, 00:54:13 от VestniK »

Оффлайн [DarkNet]Alpha

  • Автор темы
  • Активист
  • *
  • Сообщений: 987
  • Эмоциональный эльдар
    • Просмотр профиля
    • EBM-радио
Re: C++, strupr и указатели
« Ответ #4 : 06 Октября 2010, 00:53:25 »
О, спасибо, добрый человек.
Можете кратко рассказать или дать хорошую ссылку про указатели? Я испорчен паскалем и питоном, и такое насилие над строками не могу понять...

Оффлайн Kwah

  • Старожил
  • *
  • Сообщений: 1442
  • Ubuntu 17.10
    • Просмотр профиля
Re: C++, strupr и указатели
« Ответ #5 : 06 Октября 2010, 00:55:35 »
Вот так работает
#include <stdio.h>
#include <string.h>
#include <ctype.h>

void strupr(char*);

int main()
{
    char pstr1[] = "ololowcase";
    strupr(pstr1);
    printf("%s\n", pstr1 );
    return 0;
}

void strupr(char *s){
    char *res=s;
    while(*s!='\0'){
        *res=toupper(*s);
        s++;
        res++;
    }
}

Оффлайн VestniK

  • Активист
  • *
  • Сообщений: 594
    • Просмотр профиля
Re: C++, strupr и указатели
« Ответ #6 : 06 Октября 2010, 01:17:12 »
Ну а что именно интересует? Указатель это просто адрес области памяти где лежат твои данные. В C/C++ есть арифметические операции над указателями, но с ними лучше быть аккуртней. Через них можно получить указатель на область памяти которая твоему приложению не принадлежит и при попытки что-нибудь с этой памятью сделать ты олучишь сегфолт.

А так всё просто например обрати внимание на "случайное" совпадение в выводе следующей программы:
#include <stdio.h>

int main(int argc, char **argv)
{
    int  a[5];
    long long b[5];

    int  *ptr_i  = a;
    long long *ptr_ll = b;

    size_t dist_i  = (size_t)(ptr_i+1) - (size_t)ptr_i;
    size_t dist_ll = (size_t)(ptr_ll+1) - (size_t)ptr_ll;

    printf("dist_i  = '%d'; sizeof(int)       = '%d'\n", dist_i , sizeof(int));
    printf("dist_ll = '%d'; sizeof(long long) = '%d'\n", dist_ll, sizeof(long long));

    return 0;
}

@Kwah а зачем обоих сдвигать? Это же пустая трата времени на ненужную дополнительную арифметическую операцию в теле цикла.

Оффлайн [DarkNet]Alpha

  • Автор темы
  • Активист
  • *
  • Сообщений: 987
  • Эмоциональный эльдар
    • Просмотр профиля
    • EBM-радио
Re: C++, strupr и указатели
« Ответ #7 : 06 Октября 2010, 01:25:22 »
Такс... strlwr и strupr осилил, до кучи написал strrev. Попытался встроить это в string.h, но этот файл поверг меня в ужас. Стоит ли искать в нём начала и концы, или пусть себе будет strex?

Оффлайн Toxic

  • Новичок
  • *
  • Сообщений: 10
  • Get Lo
    • Просмотр профиля
Re: C++, strupr и указатели
« Ответ #8 : 06 Октября 2010, 01:45:00 »
[DarkNet]Alpha, ошибку получаешь, потому что константную строку пытаешься модифицировать. Создай буфер, пихни в него строку и передавай указатель на буфер. Посмотри как сделан pstr1 у Kwah. И не забываем про arguments sanity check - внутри функции обязательно проверку аргумента на NULL поставь.
« Последнее редактирование: 06 Октября 2010, 01:59:12 от Toxic »

Оффлайн Kwah

  • Старожил
  • *
  • Сообщений: 1442
  • Ubuntu 17.10
    • Просмотр профиля
Re: C++, strupr и указатели
« Ответ #9 : 07 Октября 2010, 01:59:19 »
@Kwah а зачем обоих сдвигать? Это же пустая трата времени на ненужную дополнительную арифметическую операцию в теле цикла.
Ну, оригинал написан с использованием двух указателей. Из-за того, что res++ отсутсвует получается бесконечный цикл, затирающий сначала оригинальную строку, а потом всё подряд после неё. Ну... И инерционность мышления ;)

Интересно, а оптимизатор эту лишнюю арифметическую операцию не распознает?

Оффлайн VestniK

  • Активист
  • *
  • Сообщений: 594
    • Просмотр профиля
Re: C++, strupr и указатели
« Ответ #10 : 07 Октября 2010, 02:17:34 »
ну можно попробовать скомпилировать с -O0 -O1 -O2 -O3 и посмотреть дизасемблером на эту функцию, вот только я не знаю как дизасемблером пользоваться (в особенности, как там найти конкретную функцию)

 

Страница сгенерирована за 0.017 секунд. Запросов: 22.