преобразование строки в структуру в C - PullRequest
0 голосов
/ 20 января 2019

Недавно я практиковался в обработке ФАЙЛА на C, поэтому я написал программу, которая считывает файл символ за символом и сохраняет вывод в виде строки (очень долго). Мой файл содержит различные имена, разделенные табуляцией, одна строка имеет 3 имени следующим образом.

Name1 Name2 Name3
Name4 Name5 Name6
Name7 Name8 Name9

В результате написанной мной функции теперь у меня есть строка [Имя1 Имя2 Имя3 Имя4 Имя5 Имя5 ....]

Теперь я хочу сохранить эти имена в структуре. Я написал следующую функцию для этого.

  #include<stdio.h>
  #include<stdlib.h>
  #define MAX_LENGTH 30
  struct sarray
  {
  char data[MAX_LENGTH]
  };


  char* stringtoarray(char longstring[],int totalchar,int totaldata)
  {
  int i=0,j=0;
  char che;
  struct sarray say[totaldata];
  char* resultptr;
  che=longstring[i];

  while(che!='NULL')
  {

    if(che=='\t' || che=='\n')
    {
        j++;
        i=0;
    }
    else
    {
        say[j].data[i]=che;
        i++;
    }
    che=longstring[i];
}
resultptr=&say->data;
return resultptr;

}

Ниже приведены аргументы функции.

  1. longstring [] - это строка (вывод символа из файла символов считывается)
  2. totalchar - Общее количество символов в длинной строке []
  3. totaldata - Общее количество имен.

Я пытался вызвать вышеуказанную функцию из основной функции, но она не показывает никаких результатов, хотя и не выдает ошибку во время компиляции.

Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Есть проблемы с вашим кодом.

1 / Как уже упоминалось, вы возвращаете указатель на локально распределенные данные.Когда вы объявляете локальную структуру / массив в функции, пространство для хранения структуры выделяется в стеке и «теряется» при выходе из функции.Таким образом, возвращаемый указатель будет указывать на мусор.

Единственный способ - выделить данные в куче с помощью malloc.

заменить struct sarray say[totaldata]; на

struct sarray *say;
say = (struct sarray *) malloc(totaldata * sizeof(struct sarray));

2 / NULL не является символом.Если вы хотите проверить конец вашей входной строки, замените while(che != 'NULL') на while(che != '\0')

3 / возвращая & скажем-> данные неверны.Если вы хотите получить всю информацию, просто верните указатель на ваш массив структур (и измените объявление функции).

4 / Отсутствует много проверок работоспособности

5 / почемуу вас есть неиспользуемый параметр в вашем func (totalchar)

6 /, и вы должны переосмыслить свой алгоритм, например, используя scanf, как уже указано.

0 голосов
/ 20 января 2019

Вы можете сделать себе большую пользу, прочитав формат, который вы хотите в первую очередь, вместо отдельных символов:

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

#define STR(X)        #X
#define STRINGIFY(X)  STR(X)

#define MAX_TOKEN_LENGTH  30
#define TOKENS_GROWTH      3

typedef struct token_tag {
    char data[MAX_TOKEN_LENGTH + 1];
} token_t;

int main(void)
{
    char const *filename = "test.txt";
    FILE *input = fopen(filename, "r");
    if (!input) {
        fprintf(stderr, "Couldn't open \"%s\" for reading :(\n\n", filename);
        return EXIT_FAILURE;
    }

    char token[MAX_TOKEN_LENGTH + 1];
    size_t tokens_size  = 0;
    size_t num_tokens   = 0;
    token_t *tokens     = NULL;

    while (fscanf(input, "%" STRINGIFY(MAX_TOKEN_LENGTH) "s", token) == 1) {
        if (num_tokens == tokens_size) {
            token_t *tmp_tokens = realloc(tokens, (tokens_size + TOKENS_GROWTH) * sizeof(*tmp_tokens));
            if (!tmp_tokens) {
                fputs("Not enough memory :(\n\n", stderr);
                break;
            }
            tokens_size += TOKENS_GROWTH;
            tokens = tmp_tokens;
        }
        memcpy(tokens[num_tokens++].data, token, MAX_TOKEN_LENGTH + 1);
    }
    fclose(input);

    for (size_t i = 0; i < num_tokens; ++i)
        printf("Token #%02zu: \"%s\"\n", i + 1, tokens[i].data);

    free(tokens);
}

Вывод:

Token #01: "Name1"
Token #02: "Name2"
Token #03: "Name3"
Token #04: "Name4"
Token #05: "Name5"
Token #06: "Name6"
Token #07: "Name7"
Token #08: "Name8"
Token #09: "Name9"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...