在C中将字符串转换为结构

时间:2019-01-20 13:16:49

标签: c arrays struct

最近我在C语言中练习FILE处理,因此我写了一个程序,可以逐个字符读取文件,并将输出存储为字符串(很长)。我的文件包含用制表符分隔的各种名称,一行包含3个名称,如下所示。

Name1 Name2 Name3
Name4 Name5 Name6
Name7 Name8 Name9

由于编写了函数,现在我有了一个字符串[Name1 Name2 Name3 Name4 Name5 Name6 ....]

现在,我想将这些名称存储到结构中。我已经为其编写了以下函数。

  #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-名称总数。

我试图从main函数调用上述函数,但是它没有显示任何结果,尽管在编译过程中没有错误。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

首先阅读所需的格式,而不要使用单个字符,这样可以帮自己一个大忙:

#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"

答案 1 :(得分:1)

您的代码有任何问题。

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 /返回&say->数据不正确。如果要获取所有信息,只需返回一个指向结构数组的指针(并更改func的声明)即可。

4 /许多健全性检查缺失

5 /为什么在func(总字符)中有未使用的参数

6 /,您应该重新考虑算法,例如,如前所述,使用scanf。