2010-11-12 52 views
1

我想分割一个字符串每X个字符,然后将每行存储在一个结构数组中。但是,我想知道这将是一个简短有效的方法。我想也许我可以使用sscanf,但不是很确定如何。任何帮助将不胜感激。到目前为止,我有:C - 拆分/存储字符串的X长度到结构数组

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

struct st {char *str;}; 

int main() 
{ 
    struct st **mystruct; 

    char tmp[] = "For configuration options (arch/xxx/config.in, and all the Config.in files),somewhat different indentation is used."; 
    size_t max = 20, j = 0; // max length of string 
    size_t alloc = strlen(tmp)/max + 1; 

    mystruct = malloc(alloc * sizeof *mystruct); 
    for (j = 0; j < alloc; j++) 
     mystruct[j] = malloc(sizeof *mystruct[j]); 

    const char *ptr = tmp; 
    char field [ max ]; 
    int n; 

    while (*ptr != '\0') { 
     int line = sscanf(ptr, "%s", field, &n); // not sure how to use max in here 
     mystruct[j]->str = field; 
     field[0]='\0'; 
     if (line == 1) 
      ptr += n; 
     if (n != max) 
      break; 
     ++ptr; 
     ++j; 
    } 

    return 0; 
} 

所以,当我遍历我的结构,我能得到这样的:

For configuration op 
tions (arch/xxx/conf 
ig.in, and all the C 
onfig.in files),some 
what different inden 
tation is used. 

回答

3

你可以使用strncpy()函数。

FYI:

char field [ max ]; 
while (...) { 
    mystruct[j]->str = field; 

两个问题:(1)您的阵列中的每个结构将要结束了在相同的字符串,这将有你扫描的最后一件事的价值指向,( 2)它们指向栈上的变量,所以当这个函数返回时,它们将被丢弃。这不会在这里明显地表现出自己(例如,你的程序不会爆炸),因为函数恰好是'main',但是如果你将它移动到一个单独的例程并调用它来解析一个字符串,你会回到垃圾。

mystruct不需要是指向指针的指针。对于一维数组,只需为N个元素分配一个块N * sizeof *myarray

处理结构时常见的C语言习惯是使用typedef,因此您不必一直键入struct foo。例如:

typedef struct { 
    int x, y; 
} point; 

现在不是打字struct point pt你可以说point pt

+0

当你说使用strncpy时,你能详细说一点吗?谢谢 – demit1501 2010-11-12 20:21:33

1

如果字符串是不会改变你把它分解后,我建议使用这样的结构:

struct st { 
    char *begin; 
    char *end; 
}; 

或替代方案:

struct st { 
    char *s; 
    size_t len; 
}; 

然后,而不是创建所有这些新字符串,只需标记每个字符开始和结束的地方。将原始字符串保留在内存中。

+0

我不喜欢这些想法,因为在所有情况下,这些'char *'不会指向代表各个行的正确以null结尾的字符串。因此,例如,如果他要遍历结构并调用类似于'printf(“%s \ n”,s.begin)'的命令,那么输出结果将不符合要求。 – 2010-11-12 20:08:53

+0

@Dave:这样做:const char * p = s.begin; while(p!= s.end)putchar(* p ++); – 2010-11-12 20:25:28

+1

@Dave:或者使用start和len版本:printf(“%。* s \ n”,s.len,s.s); – 2010-11-12 20:28:17

0

一种选择是逐字符地进行。

计算您当前正在执行的行数。

分配内存=(strlen的(TMP)+ NUMBER_OF_LINES)*的sizeof(char)的

走过你的输入字符串,从输入到新分配的内存复制的字符。每隔20个字符,插入一个空字节来限定该字符串。将指针保存到结构数组中每行的开始位置。

0

它很容易吗?

#define SMAX 20 
typedef struct {char str[SMAX+1];} ST; 

int main() 
{ 
    ST st[SMAX]={0}; 
    char *tmp = "For configuration options (arch/xxx/config.in, and all the Config.in files),somewhat different indentation is used."; 
    int i=0,j; 
    for(; (st[i++]=*(ST*)tmp).str[SMAX]=0 , strlen(tmp)>=SMAX; tmp+=SMAX); 

    for(j=0;j<i;++j) 
    puts(st[j].str); 

    return 0; 
} 
0

您可以使用(非C标准但GNU)函数strndup()。

#define _GNU_SOURCE 
#include <string.h> 

struct st {char *str;}; 

int main() 
{ 
    struct st *mystruct; /* i wonder if there's need for double indirection... */ 

    char tmp[] = "For configuration options (arch/xxx/config.in, and all the Config.in files),somewhat different indentation is used."; 
    size_t max = 20, j = 0; // max length of string 
    size_t alloc = (strlen(tmp) + max - 1)/max; /* correct round up */ 

    mystruct = malloc(alloc * sizeof mystruct); 
    if(!mystruct) return 1; /* never forget testing if allocation failed! */ 

    for(j = 0; j<alloc; j++) 
    { 
     mystruct[j].str = strndup(tmp+alloc*max, max); 
    } 
}