Создание пользовательского метода в верхнем регистре

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

Вот пример:

Для инициализации:

char *Register[5];

Внутри моего пока:

char *p;
int i =0;
for(i=0;i<=4;i++)
{
    if(i==0)p="test1";
    if(i==1)p="test2";
    if(i==2)p="test3";
    if(i==3)p="test4";
    Register[i]=ToUpper(p);
}
Eusart2_Write(Register[0]);
__delay_ms(20);
Eusart2_Write(Register[1]);
__delay_ms(20);
Eusart2_Write(Register[2]);
__delay_ms(20);
Eusart2_Write(Register[3]);

А вот и мой верхний метод:

char *ToUpper(char *string)
{
    int i=0;
    char txt[255]="";
    char Buffer[255]="";

    strcpy(Buffer,string);

    for(i = 0; i<=strlen(Buffer); i++)
    {
        if(( Buffer[i]>='a')&&( Buffer[i]<='z'))
            txt[i]=Buffer[i] - 32; 
        else
            txt[i]= Buffer[i];  
    }
    txt[i++]='\0';

    return txt;
}

В моем выводе я беру один и тот же результат для всех регистров:

TEST4TEST4TEST4TEST4

У вас есть несколько проблем с кодом, который вы показываете, самая важная из которых заключается в том, что это не Минимальный, полный и проверяемый пример. Также пожалуйста читай о том, как задавать хорошие вопросы и этот контрольный список вопросов.

Some programmer dude 10.09.2018 09:28

Однако с Угадай происходит то, что у вас есть единый массивtxt, и вы назначаете все указатели в Register, чтобы они указывали на первый элемент этого единственного массива. Т.е. все указатели будут указывать на одно и то же место.

Some programmer dude 10.09.2018 09:33

Как я могу изменить местоположение?

Dhi 10.09.2018 09:35

Одна из многих проблем: ваш массив Register состоит из 5 элементов, но вы относитесь к нему как к 21 ...

Shawn 10.09.2018 09:37

Я всегда вздрагиваю, когда кто-то реализует O (n ** 2) решение проблемы O (n).

Tom Karzes 10.09.2018 09:39

Извините, я исправил.

Dhi 10.09.2018 09:39

@TomKarzes: Действительно, хотя некоторые компиляторы достаточно умны, чтобы оптимизировать повторяющиеся вызовы strlen, в этом случае есть намеки на то, что этого не произойдет.

Bathsheba 10.09.2018 09:40

Вместо того, чтобы создавать массив указателей, сделайте его массивом массивы. Затем скопируйте строку в Register[i] и измените функцию ToUpper, чтобы изменить строку на месте.

Some programmer dude 10.09.2018 09:41

Вы можете показать мне пример, сэр?

Dhi 10.09.2018 09:42

И примечание о стиле: прекратите использовать магические числа. Если, например, 97 вы имеете в виду кодировку ASCII для 'a', затем так сказать. Еще лучше использовать функцию стандартtoupper.

Some programmer dude 10.09.2018 09:42

Исправляю в своем вопросе. Но почему он всегда пишет одно и то же место?

Dhi 10.09.2018 09:47

Возможный дубликат Возврат массива с помощью C

Sander De Dycker 10.09.2018 09:50

Пожалуйста, сэр, напишите мне пример

Dhi 10.09.2018 09:55
0
13
167
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Ваш массив txt является локальным для функции ToUpper. Как только он выходит за рамки, вы не можете гарантировать, каким будет его содержимое. Поэтому, если ваша переменная Register является глобальной, вы также можете сделать глобальным массив txt.

Во-вторых, вы пишете только после преобразования ВСЕХ строк в верхний регистр. Таким образом, даже если ваш массив txt был глобальным, он будет содержать только то, что было записано в него самым последним (то есть «TEST4»). Решение этой проблемы - писать сразу после преобразования. Итак, переместите запись в цикл for следующим образом:

for(i=0;i<=4;i++)
{
    if(i==0)p="test1";
    if(i==1)p="test2";
    if(i==2)p="test3";
    if(i==3)p="test4";
    Register[i]=ToUpper(p);
    Eusart2_Write(Register[i]);
    __delay_ms(20);
}

Примечание: у вас есть только четыре строки в цикле for, который имеет 5 итераций, поэтому, когда вы пишете, вы в конечном итоге напишете TEST4 дважды, потому что p сохранит "test4", когда i равно 4. Поэтому вам нужно исправить управляющее выражение в Петля for тоже.

Однако, если вы хотите сохранить значения в Register и распечатать их после цикла for, вам нужно сделать регистр двумерным массивом и скопировать в него возвращаемое значение ToUpper.

Ваша регистрационная декларация будет выглядеть так:

char Register[5][6];  

и ваш цикл for будет выглядеть так:

for(i=0;i<4;i++)
{
    if(i==0)p=(char*)"test1";
    if(i==1)p=(char*)"test2";
    if(i==2)p=(char*)"test3";
    if(i==3)p=(char*)"test4";
    strcpy(Register[i], ToUpper(p));
    printf("%s\n", &Register[i]); 
}

См. Этот пример.

Спасибо за ответ, но в вашем методе все регистры будут иметь одно и то же имя. Я смогу распечатать их правильно, но когда я буду использовать их в своем коде, у меня будет одно и то же имя во всех регистрах.

Dhi 10.09.2018 10:26

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

P.W 10.09.2018 10:39

Да, если я буду использовать регистр [2] после того, как мой цикл напечатает TEST4

Dhi 10.09.2018 10:46

Вот код, вы можете увидеть результат, он печатается правильно: coliru.stacked-crooked.com/a/d593674a60b92cb3

P.W 10.09.2018 11:19

Да, поэтому я напечатал внутри цикла for. Если вы хотите сохранить значения в Register, вам нужно сделать Register как двумерный массив и скопировать в него возвращаемое значение ToUpper.

P.W 10.09.2018 11:26

Спасибо, сэр, это пример, который я прошу. Вы можете привести мне пример с этим?

Dhi 10.09.2018 11:30

Также лучше использовать массив символов вместо указателей?

Dhi 10.09.2018 11:36

Удовлетворяет ли вас последний приведенный мною пример?

P.W 10.09.2018 12:09

Добро пожаловать. Я обновлю ответ, чтобы включить это решение.

P.W 10.09.2018 12:22

Ваша проблема в том, что вы возвращаете txt.

Txt - это только локальный указатель на символ, который существует только внутри функции ToUpper.

С участием

Register[i]=ToUpper(p);

вы назначаете этот указатель на Register [i].

Теперь вы снова вызываете ToUpper, и старый текстовый текст будет перезаписан следующими символами TEST2.

Теперь Register [0] указывает на начало текста TEST2.

Это продолжается до последнего вызова test4.

Затем все регистры [0..3] указывают на одно и то же место, и это будет начало последнего txt-символа (TEST4). Итак, вы печатаете TEST4 4 раза.

(Большая проблема в том, что память txt больше не выделяется и может измениться в любое время во время выполнения)

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

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <fstream>

char *Register[5];

char *ToUpper(char *const string)
{
    int i=0;

    for(i = 0; i<=strlen(string); i++)
    {
        if(( string[i]>='a')&&( string[i]<='z'))
            string[i]=string[i] - 32;   
    }

    return string;
}

int main () {
    int i =0;
    for(i=0;i<=4;i++)
    {
        Register[i]=(char*)malloc(strlen("testN"));
        if(i==0)strcpy(Register[i],"test1");
        if(i==1)strcpy(Register[i],"test2");
        if(i==2)strcpy(Register[i],"test3");
        if(i==3)strcpy(Register[i],"test4");
        ToUpper(Register[i]);
    }
    printf("%s",Register[0]);
    printf("%s",Register[1]);
    printf("%s",Register[2]);
    printf("%s",Register[3]);

   return(0);
}

обратите внимание, что код работает только благодаря фиксированным размерам ваших примеров. Поскольку я не знаю, что вы хотите сделать, пожалуйста, измените фиксированную длину malloc так, как вам нужно.

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

Dhi 10.09.2018 10:25

Он ничего не печатает ... Также в верхнем регистре мне нужна строка или * строка?

Dhi 10.09.2018 10:54

просто скопируйте весь код и вставьте его сюда coliru.stacked-crooked.com, затем нажмите "Compile Link run ...", это работает

Muperman 10.09.2018 10:59

Другие вопросы по теме