Member 14880089 Ответов: 2

Изменение двойной указатель типа char в указатель типа int


Я должен изменить приведенный ниже код, превратив char** end в findInteger в int* end

int findInteger(const char str[81], char** end) {
    int i = (int)(*end - str), j = 0;
    bool isNum = false;
    char str1[40];
    char prev = ' '; //instead of str[0], if number at beginning
    while (str[i]) {
        if (isdigit(str[i])) {
            if (!isNum && (prev == ' ' || prev == '\t' || prev == ',' || prev == '.' || prev == '!' || prev == '\0')) isNum = true;
            if (isNum) {
                str1[j] = str[i];
                j += 1;
            }
        }
        else {
            if (isNum) {
                if (str[i] == ' ' || str[i] == '\t' || str[i] == ',' || str[i] == '.' || str[i] == '!' || str[i] == '\0') {
                    str1[j] = 0;
                    *end = (char*)&(str[i]);
                    return atoi(str1);
                }
                else {
                    isNum = false; j = 0;
                }
            }
        }
        prev = str[i];
        i += 1;
    }
    if (isNum) {
        str1[j] = 0;
        *end = (char*)&(str[i]);
        return atoi(str1);
    }
    *end = (char*)&(str[i]);
    return NULL;
}

int getNumbers(const char str[81], int numbers[40]) {
    char* end = (char*)str;
    int c = 0, num;
    while (*end) {
        if ((num = findInteger(str, &end)) != NULL) {
            numbers[c] = num;
            c += 1;
        }
    }
    return c;
    //return 0;
}

int main() {
    char string[20][81];
    int string_count;

    input_printf("Input number of lines (integer in the range [1,20]): \n");
    scanf("%d", &string_count);
    scanf("%*1[\n]");


    if (string_count < 1 || string_count > 20)
    {
        error_printf("invalid input data");
        return 0;
    }

    input_printf("Input text: \n");
    for (int i = 0; i < string_count; i++)
    {
        gets_s(string[i]);
    }

    for (int i = 0; i < string_count; i++) {
        int num[40];
        int length1 = getNumbers(string[i], num);

        if (length1 == 0) {
            error_printf("no solution");
        }

        else {
            //printf("%d\n", length1);
            for (int j = 0; j < length1; j++) printf("%d  ", num[j]);
            printf("\n");
        }

        return 0;
    }
}


Что я уже пробовал:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "str_unit.h"
#include "testing.h"
#pragma warning(disable : 4996)

int findInteger(const char str[81], int* end) {
    int i = strlen(str), j = 0;
    bool isNum = false;
    char str1[40];
    char prev = ' '; //instead of str[0], if number at beginning
    while (str[i]) {
        if (isdigit(str[i])) {
            if (!isNum && (prev == ' ' || prev == '\t' || prev == ',' || prev == '.' || prev == '!' || prev == '\0')) isNum = true;
            if (isNum) {
                str1[j] = str[i];
                j += 1;
            }
        }
        else {
            if (isNum) {
                if (str[i] == ' ' || str[i] == '\t' || str[i] == ',' || str[i] == '.' || str[i] == '!' || str[i] == '\0') {
                    str1[j] = 0;
                    end = (int*)&(str[i]);
                    //return atoi(str1);
                }
                else {
                    isNum = false; j = 0;
                }
            }
        }
        prev = str[i];
        i += 1;
    }
    if (isNum) {
        str1[j] = 0;
        end = (int*)&(str[i]);
        //return atoi(str1);
    }
    end = (int*)&(str[i]);

}

int getNumbers(const char str[81], int numbers[40]) {

    int end = atoi(str);
    int c = 0, num;
    while (end) {
        if ((num = findInteger(str, &end)) != NULL) {
            numbers[c] = num;
            c += 1;
        }
    }
    return c;
}

int main() {
    char string[20][81];
    int string_count;

    input_printf("Input number of lines (integer in the range [1,20]): \n");
    scanf("%d", &string_count);
    scanf("%*1[\n]");


    if (string_count < 1 || string_count > 20)
    {
        error_printf("invalid input data");
        return 0;
    }

    input_printf("Input text: \n");
    for (int i = 0; i < string_count; i++)
    {
        gets_s(string[i]);
    }

    for (int i = 0; i < string_count; i++) {
        int num[40];
        int length1 = getNumbers(string[i], num);

        if (length1 == 0) {
            error_printf("no solution");
        }

        else {
            //printf("%d\n", length1);
            for (int j = 0; j < length1; j++) printf("%d  ", num[j]);
            printf("\n");
        }

        return 0;
    }
}


Но это все равно не работает, и главная проблема исходит от функции getInteger

Garth J Lancaster

"Но это все равно не работает" - возможно, вы хотели бы использовать "улучшить вопрос" и показать/указать, почему он не работает или что вы получаете за различные входные данные - мы не можем читать ваш экран или ваш разум

2 Ответов

Рейтинг:
2

W∴ Balboos, GHB

Когда вам доступна опция создания объединения указателей.

Простой пример:

union myPointers {
  char * c;
  int  * i;
}

Теперь все, что вам нужно сделать, это установить значение указателя на (первый) символ в
член "С" в struture, а затем прочитать его обратно через член "i".

Что-то похожее на:
union myPointers x;
x->c = s;  // s is the address of the your char string
           // *x->i contains an array of int's  addressible as an
           // indexed array if you like


Вы можете добавить другие типы к этому виду объединения.

Это можно сделать и другими способами C - Союзы - Tutorialspoint[^]


Рейтинг:
0

OriginalGriff

Первое, что вам нужно узнать, это то, что int*и char* вы не можете предположить, что допустимый указатель char даст допустимый указатель int - потому что указатели int должны находиться на границах 2, 4 или 8 байт (в зависимости от размера int в вашей системе), в то время как указатели char являются однобайтовыми границами. Таким образом, "нечетное" значение в указателе char не будет ссылаться на одну и ту же ячейку памяти при обработке как указатель int - некоторые из наименее значимых битов будут отброшены или проигнорированы. Вы должны знать об этом, если вы также меняете код вызова.

Кроме этого,

Цитата:
это все еще не работает

ничего не говорит нам: мы знаем, что есть проблема, иначе вы не стали бы писать здесь.
Цитата:
основная проблема исходит от функции getInteger

Также ничего нам не говорит, потому что в вашем коде нет такой функции!

Так что все будет зависеть от тебя.
К счастью, у вас есть инструмент, который поможет вам выяснить, что происходит: отладчик. Как вы его используете, зависит от вашей системы компилятора, но быстрый поиск в Google имени вашей IDE и "отладчика" должен дать вам необходимую информацию.

Поместите точку останова в первую строку функции и запустите код через отладчик. Затем посмотрите на свой код и на свои данные и определите, что должно произойти вручную. Затем по одному шагу в каждой строке проверяйте, что то, что вы ожидали, произойдет именно так, как и произошло. Когда это не так, тогда у вас есть проблема, и вы можете вернуться назад (или запустить ее снова и посмотреть более внимательно), чтобы выяснить, почему.

Извините, но мы не можем сделать это за вас - пришло время вам освоить новый (и очень, очень полезный) навык: отладку!


KarstenK

Разве не все указатели имеют одинаковый размер в зависимости от настроек компилятора? (Но память, на которую они указывают, должна быть другой)