编写struct +只保存指针?

时间:2015-04-26 11:39:57

标签: c

我在变量n0中为struct节点分配空间。我使用fwrite将这个结构保存到文件中,但很多人说我只保存指向ustr的指针。但我需要保存字符串ustr,你能帮忙吗?

public class GraphActivity extends Activity {

LinearLayout chart;
private View mChart;
private static final int SERIES_NR = 2;
int[] income = {102, 95, 97, 100, 92, 99, 88};


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_graph);
    chart = (LinearLayout) findViewById(R.id.chart);

    XYMultipleSeriesRenderer renderer = getTruitonBarRenderer();
    myChartSettings(renderer);
    mChart = ChartFactory.getBarChartView(this, getTruitonBarDataset(), renderer, BarChart.Type.DEFAULT);
    chart.addView(mChart);
}

private XYMultipleSeriesDataset getTruitonBarDataset() {
    XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
    final int nr = 4;
    Random r = new Random();
    int[] x = { 0,1,2,3,4,5,6};
    CategorySeries series = new CategorySeries("INCOME");
    for(int i=0;i<x.length;i++){
        series.add(income[i]);
    }
    dataset.addSeries(series.toXYSeries());
    return dataset;
}

public XYMultipleSeriesRenderer getTruitonBarRenderer() {
    XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
    renderer.setAxisTitleTextSize(50);
    renderer.setChartTitleTextSize(20);
    renderer.setLabelsTextSize(25);
    renderer.setLegendTextSize(15);
    SimpleSeriesRenderer r = new SimpleSeriesRenderer();
    r.setColor(Color.BLUE);
    renderer.addSeriesRenderer(r);
    return renderer;
}

private void myChartSettings(XYMultipleSeriesRenderer renderer) {
    renderer.setXAxisMin(0.8);
    renderer.setXAxisMax(7.1);
    renderer.setYAxisMin(50);
    renderer.setYAxisMax(220);
    renderer.addXTextLabel(1, "Tue");
    renderer.addXTextLabel(2, "Wed");
    renderer.addXTextLabel(3, "Thu");
    renderer.addXTextLabel(4, "Fri");
    renderer.addXTextLabel(5, "Sat");
    renderer.addXTextLabel(6, "Sun");
    renderer.addXTextLabel(7, "Today");
    renderer.setYLabelsAlign(Paint.Align.RIGHT);
    renderer.setBarWidth((float)25);

    renderer.setShowAxes(false);
    renderer.setShowLegend(false);

    renderer.setMargins(new int[] {0,50,0,20});

    renderer.setApplyBackgroundColor(true);
    renderer.setBackgroundColor(Color.TRANSPARENT);
    renderer.setMarginsColor(Color.argb(0x00, 0xff, 0x00, 0x00));
    renderer.setShowGrid(true);
    renderer.setShowGridY(false);
    renderer.setGridColor(Color.GRAY);
    renderer.setXLabels(0); // sets the number of integer labels to appear
}

3 个答案:

答案 0 :(得分:1)

sizeof(node)错误,因为它使用int的大小和pointer的大小,而不是string的大小。您必须分配string作为例如unsigned char ustr[10]或动态分配字符串,但使用您分配的字符来查找大小,并提供字符串指向fwrite的指针。

如果您静态分配字符串,这应该有效:

fwrite(&n0, sizeof(node), 1, file_ptr);

否则,如果你动态分配字符串,你应该这样做:

fwrite(&(n0 + sizeof(unsigned char *)), sizeof(int), 1, file_ptr);
fwrite(n0.ustr, length_node, 1, file_ptr);

或更好:

fwrite(&n0.height, sizeof(int), 1, file_ptr);
fwrite(n0.ustr, length_node, 1, file_ptr);

答案 1 :(得分:1)

我也在你的另一个问题中回答了这个问题,但基本上,只是分别编写两个字段而不是一次编写整个结构:

int main() {
    const int count = 2;
    FILE* file_ptr = fopen("file1", "w+");
    node n0;
    node_init(&n0,count);
    /* write length of string so reader will know how much to read back */
    fwrite(&count, sizeof(count), 1, file_ptr);
    fwrite(n0.ustr, count, 1, file_ptr);
    fwrite(&n0.height, sizeof(n0.height), 1, file_ptr);
    fclose(file_ptr);
    node_destroy(&n0);

    return 0;
}

答案 2 :(得分:1)

如果在编译时修复了元素ustr的数量,请将其设为包含该元素数量的数组,并且不要malloc()它。这确保了数组而不是指针被写入。

如果在编译时未修复字符串的长度(例如,从用户输入派生的整数值) - 并且您希望能够使用fread()在另一时间再次读取结构,并获得与写入相同的数据 - 然后你需要在结构中存储长度,并使用两个fwrite()调用(第一个需要保存长度,第二个需要输出字符数)。例如;

typedef struct
{
    int height;           /*  note change of order of member */
    int ustr_length;
    unsigned char * ustr;
} node;

void node_init(node * n, int r)
{
    int i;
    n->ustr = malloc((r + 1) * sizeof(unsigned char));
    n->ustr_length = r+1;       /*  save the length of u->str */
    for (i = 0; i < r; i++) {
        (n->ustr)[i] = random() & 0xff;
    }
    (n->ustr)[r] = 0;
    n->height = -1;
}
void node_destroy(node * n)
{
    free(n->ustr);
    n->height = -1;
    n->ustr_length = 0;
}

int main()
{
    FILE* file_ptr = fopen("file1", "w+");
    node n0;
    node_init(&n0,2);
    fwrite(&n0.height, 2*sizeof(int), 1, file_ptr);
    fwrite(n0.ustr, n0.ustr_length, 1, file_ptr);
    fclose(file_ptr);
    node_destroy(&n0);
    return 0;
}

将其转换为可以使用fread()读取数据并重建原始结构的代码是微不足道的。

进行错误检查是个不错的主意。 malloc()fopen()fwrite()fread()等等都可能失败,而忽略这是危险的。