Как отсканировать несколько строк из длинной строки и сохранить их в слове char * [20]? - PullRequest
1 голос
/ 21 апреля 2019
            int res, charRead;
            char *ptr = buff;
            char *searchWord[20];
            int j = 0;
            while(1)
            {
                res = sscanf(ptr, "%s%n", searchWord[j] ,&charRead);
                if(res != 1)
                {
                    break;
                }

                printf("%s\n", searchWord[j]);
                j++;
                ptr = ptr + charRead;

            }

В массив баффов включены некоторые строки.Например, если бафф содержит «привет мир».Результат должен быть таким: searchWord [0] = "hello", searchWord [1] = "world".Я пытаюсь переместить каждое слово из этого длинного массива в другой массив указателей.Однако я получаю ошибки сегмента и неправильные записи.Спасибо за вашу помощь.

            int j = 0;
            char searchWord[20][20];
            char *ptr;
            ptr = strtok(buff, " ");
            while(ptr != NULL)
            {
                strncpy(searchWord[j][], ptr, 20);
                j++;
                ptr = strtok(NULL, " ");
            }

Это измененный вариант, однако как его инициализировать, чтобы он не вызывал никаких проблем.

1 Ответ

0 голосов
/ 21 апреля 2019

@ abhiarora Не могли бы вы подсказать, как распределить это пространство в куче с помощью malloc?

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

Я протестировал и скомпилировал приведенный ниже код на моей Ubuntu 18.04 машине с gcc (gcc (Ubuntu 8.2.0-7ubuntu1) 8.2.0).

Команда компиляции была gcc test.c -o test -Wall -Wextra.

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

#include <stdlib.h>


int method1(const char *buffer, char *arrayOfPtr[50], const int MAX_NUM)
{
    int ndx = 0;

#define MAX_SIZE                    200
    char temp[MAX_SIZE + 1];

    // Method 1
    while (ndx < MAX_NUM) {
        int charRead = 0;
        if (sscanf(buffer, " %s%n", temp, &charRead) != 1)
            break;

        arrayOfPtr[ndx] = malloc(strlen(temp) + 1);
        if (arrayOfPtr[ndx] == NULL)
            break;

        memcpy(arrayOfPtr[ndx], temp, strlen(temp) + 1);
        buffer += charRead;
        ndx++;
    }

    return ndx;
}

int method2(const char *buffer, char *arrayOfPtr[50], const int MAX_NUM)
{
    char *temp = malloc(strlen(buffer) + 1);
    memcpy(temp, buffer, strlen(buffer) + 1);

    int ndx = 0;
    // Method 2
    while (ndx < MAX_NUM) {
        arrayOfPtr[ndx] = strtok(ndx ? NULL : temp, " ");
        if (arrayOfPtr[ndx] == NULL)
            break;
        ndx++;
    }

    return ndx;
}

#define MAX_NUMBER_OF_SUBSTRING             100
#define MAX_SUBSTRING_SIZE                  100

char gBuffer[MAX_NUMBER_OF_SUBSTRING][MAX_SUBSTRING_SIZE];

int method3(const char *buffer, char *arrayOfPtr[50], const int MAX_NUM)
{
    int ndx = 0;
    // Method 3
    while (ndx < MAX_NUM) {

        int charRead = 0;
        if (sscanf(buffer, " %s%n", gBuffer[ndx], &charRead) != 1)
            break;

        arrayOfPtr[ndx] = gBuffer[ndx];
        buffer += charRead;
        ndx++;
    }

    return ndx;
}


int main(int argc, char *argv[])
{
    char *bfr = "Hello World Stack Overflow";
    char *arrayOfPtr[50];

    int i;
    int size = method1(bfr, arrayOfPtr, sizeof(arrayOfPtr) / sizeof(arrayOfPtr[0]));

    for (i = 0; i < size; i++)
        printf("String: %d is \"%s\" of size %lu\r\n", i + 1, arrayOfPtr[i], (unsigned long)strlen(arrayOfPtr[i]));

    return 0;
}

Ниже приведены объяснения каждого метода:

  1. Метод номер 1: В этом методе я выделяю память динамически, используя malloc.Я использовал массив символов temp размером 200 для хранения текущей c-строки.После этого я динамически выделяю память необходимого размера и копирую строку из temp, используя memcpy.Этот метод не обрабатывает случай, когда подстрока размером более 200 была передана функции.

  2. Метод номер 2: В этом методе я имеюиспользовал функцию strtok, объявленную в #include <string.h>.Использование хорошо протестированной c-стандартной функции уменьшило количество требуемых строк кода.

  3. Метод номер 3: В этой памяти я выделил глобальный буфер дляхранение строк, чтобы нам не требовалось выделять динамическую память. Я пропустил некоторые проверки в начале этого метода .Этот метод имеет различные ограничения.Он не может работать со строками, у которых есть подстроки размером более 100 (MAX_SUBSTRING_SIZE), и не может обрабатывать строку, в которой содержится более 100 (MAX_NUMBER_OF_SUBSTRING) подстрок.Кроме того, если ваша конкретная подстрока имеет только 5 символов (например, Hello), то память 95 символов была потрачена впустую.Таким образом, это не эффективный метод.

Однако я получаю ошибки сегмента и неправильные записи.

Я бы посоветовал взглянуть наcompiler's предупреждений.Убедитесь, что у вас включено предупреждение IDE или с помощью флагов командной строки.

Я изучил такие инструменты, как valgrind и gdb.Они были очень полезны для меня при отладке моего кода для ошибок seg.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...