2010-11-12 16 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); 
    } 
}