2015-04-23 42 views
-1

我完全没有意识到为什么我的程序没有正确打印。这个程序有一个名为Customers的结构数组,它有一个称为杂货的嵌套数组结构。C编程为什么我的代码不能用嵌套的结构数组输出正确的输出?

这两个索引的(阵列中的客户)打印那里信息很好。客户1的杂货结构索引0是好的。杂货结构索引1给我C垃圾。如果有人能帮忙,我会很感激。

input.txt中:(第一个数字是客户的数量,第二个数字是第一个顾客的杂货第三个数字是第二个顾客杂货。)

2 
John Brown 
3 
Cabbage 1.50 2.5 
Cucumbers 1.00 3.0 
Tomatoes 2.99 1.5 
Mary Winters 
4 
Squash 1.48 2.5 
Zucchini 1.99 3.5 
Watercress 1.29 2.5 
Tomatoes 2.99 3.0 

我的代码输出到所谓“invoices.txt

/* Preprocessor commands */ 
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#define VEG_COL 50 

/* Defining structs/nested structs */ 
typedef struct veg{ 
    char vegName[15]; 
    float weight, unitPrice; 
} vegitable; 

/* ---------------------------------------------- */ 

typedef struct cx{ 
    char fName[15],lName[15]; 
    int numGroceries; 
    vegitable groceries[VEG_COL]; 
} customer; 

/* ---------------------------------------------- */ 




    /* Prototypes*/ 

    int numCust(FILE*); 
    void createCustomer(FILE*,customer *cx, int); 
    void createGroceryList(FILE*,vegitable *veg); 
    void printInvoice(FILE*wPtr,customer cx); 


    /* Main function */ 
    int main() { 

    FILE *ptr, *wPtr; 
    int numCustomers, i; 
     ptr = fopen("input.txt","r"); 
     wPtr = fopen("invoices.txt","w"); 

     numCustomers = numCust(ptr); 
     customer customerList[numCustomers]; 

     for(i = 0; i < numCustomers; i++) { 
      createCustomer(ptr,&(customerList[i]), i); 
     } 

     for(i = 0; i < numCustomers; i++) { 
      printInvoice(wPtr,customerList[i]); 
    } 
     fclose(ptr); 
     fclose(wPtr); 
    system("pause"); 
    return 0; 
    } 

    /* ---------------------------------------------- 
     Function that reads file for number of customers */ 

    int numCust(FILE*ptr) { 
     int num; 
     fscanf(ptr, "%d", &num);  
    return num; 

    } 

    /* ---------------------------------------------- 
     Function that reads file and creates customer */ 

    void createCustomer(FILE*ptr,customer *cx, int i) { 
     char tempF[15],tempL[15],k; 

      fscanf(ptr,"%s%s", tempF,tempL); 
      strcpy(cx->fName,tempF); 
      strcpy(cx->lName,tempL); 
      fscanf(ptr,"%d", &(cx->numGroceries)); 

       for(k=0;k<cx[i].numGroceries;k++) { 
        createGroceryList(ptr,&(cx[i].groceries[k])); 
       } 
    } 

    /* ---------------------------------------------- 
     Function that reads file and creates customers grocery list */ 

    void createGroceryList(FILE*ptr,vegitable *veg){ 
     char temp[15]; 

     fscanf(ptr,"%s%f%f", temp, &(veg->unitPrice), &(veg->weight)); 
     strcpy(veg->vegName,temp); 

    } 

    /* ---------------------------------------------- 
     Function that prints an output file for the invoice */ 

    void printInvoice(FILE*wPtr,customer cx) { 
     int k, numItems = 0; 
     float total = 0; 

      fprintf(wPtr, "Customer Name: %s %s\n\n", cx.fName,cx.lName); 
       for(k = 0; k < cx.numGroceries; k++) { 
        fprintf(wPtr, "%s \t%.1f @ %.2f\t$%.2f\n\n", cx.groceries[k].vegName,cx.groceries[k].unitPrice,cx.groceries[k].weight,cx.groceries[k].unitPrice * cx.groceries[k].weight); 
        total += (cx.groceries[k].unitPrice * cx.groceries[k].weight); 
        numItems++; 
       } 
      fprintf(wPtr, "---------------------------------------------\n\n"); 
      fprintf(wPtr, "Total\t\t\t\t$%.2f\n\n",total); 
      fprintf(wPtr, "%d items bought\n\n\n\n",numItems); 

     } 
+0

编译您的代码并启用警告,您的编译器应该对您大喊,并告诉您修复您的代码。 –

+0

尝试使用valgrind,将memset设置为0你的结构可以帮助 –

+0

@Ôrel这是Windows代码,查看无用的'system(“pause”);'显然他们使用的东西,因为'cmd.exe'也是无用的。 –

回答

0

的主要问题文件是你忽略的的返回值在你的代码中的不同位置。

第一个指出的是

fscanf(ptr,"%d", &(cx->numGroceries)); 

的情况下,发生了读取失败,例如由于数据不匹配的格式,你还在用cx->numGroceries这是未初始化,导致...? ??未定义的行为。

也在一个奇怪的方式

void createCustomer(FILE*ptr,customer *cx, int i) { 
    char tempF[15],tempL[15],k; 

     fscanf(ptr,"%s%s", tempF,tempL); 
     strcpy(cx->fName,tempF); 
     strcpy(cx->lName,tempL); 
     fscanf(ptr,"%d", &(cx->numGroceries)); 

      for(k=0;k<cx[i].numGroceries;k++) { 
       createGroceryList(ptr,&(cx[i].groceries[k])); 
       /*      ^?? */ 
      } 
} 

既可以使用指数表示法通过指针来访问的cx的阵列,或使用->操作者取消引用指针到当前cx写这个功能这实际上等同于使用.运算符的cx[0]

这里是一个版本的代码与上面已经固定

/* Preprocessor commands */ 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define VEG_COL 50 

/* Defining structs/nested structs */ 
typedef struct veg 
{ 
    char vegName[15]; 
    float weight, unitPrice; 
} vegitable; 

/* ---------------------------------------------- */ 

typedef struct cx 
{ 
    char fName[15], lName[15]; 
    int numGroceries; 
    vegitable groceries[VEG_COL]; 
} customer; 

/* ---------------------------------------------- */ 


/* Prototypes*/ 

int numCust(FILE*); 
void createCustomer(FILE*, customer *cx); 
void createGroceryList(FILE*, vegitable *veg); 
void printInvoice(FILE*wPtr, customer cx); 


/* Main function */ 
int main() 
{ 

    FILE *ptr, *wPtr; 
    int numCustomers, i; 

    ptr = fopen("input.txt", "r"); 
    if (ptr == NULL) 
     return -1; 
    wPtr = fopen("invoices.txt", "w"); 
    if (wPtr == NULL) 
    { 
     fclose(ptr); 
     return -1; 
    } 
    numCustomers = numCust(ptr); 

    customer customerList[numCustomers]; 

    for (i = 0 ; i < numCustomers ; i++) 
     createCustomer(ptr, &customerList[i]); 

    for(i = 0; i < numCustomers; i++) 
     printInvoice(wPtr, customerList[i]); 

    fclose(ptr); 
    fclose(wPtr); 

    return 0; 
} 

/* ---------------------------------------------- 
    Function that reads file for number of customers */ 

int numCust(FILE*ptr) 
{ 
    int num; 
    if (fscanf(ptr, "%d", &num) != 1) 
     return 1; 
    return num; 

} 

/* ---------------------------------------------- 
    Function that reads file and creates customer */ 

void createCustomer(FILE*ptr, customer *cx) 
{ 
    char tempF[15], tempL[15]; 
    int k; 
    /* You could use cx->fName[0], instead*/ 
    cx[0].fName[0] = '\0'; /* in case `fscanf()' fails */ 
    cx[0].lName[0] = '\0'; 
    if (fscanf(ptr, "%s%s", cx[0].fName, cx[0].lName) != 2) 
     fprintf(stderr, "Warning: failed to read first and last name.\n"); 
    if (fscanf(ptr, "%d", &(cx[0].numGroceries)) != 1) 
     cx[0].numGroceries = 0; 

    for (k = 0 ; k < cx[0].numGroceries ; k++) 
     createGroceryList(ptr, &cx[0].groceries[k]); 
} 

/* ---------------------------------------------- 
    Function that reads file and creates customers grocery list */ 

void createGroceryList(FILE *ptr, vegitable *veg) 
{ 
    veg->vegName[0] = '\0'; 
    if (fscanf(ptr, "%14s%f%f", veg->vegName, &(veg->unitPrice), &(veg->weight)) != 3) 
     fprintf(stderr, "file format error\n"); 
} 

/* ---------------------------------------------- 
    Function that prints an output file for the invoice */ 

void printInvoice(FILE*wPtr, customer cx) 
{ 
    int k, numItems = 0; 
    float total = 0; 

    fprintf(wPtr, "Customer Name: %s %s\n\n", cx.fName, cx.lName); 
    for(k = 0; k < cx.numGroceries; k++) 
    { 
     fprintf(wPtr, "%s \t%.1f @ %.2f\t$%.2f\n\n", 
      cx.groceries[k].vegName, 
      cx.groceries[k].unitPrice, 
      cx.groceries[k].weight, 
      cx.groceries[k].unitPrice * 
      cx.groceries[k].weight 
     ); 
     total += (cx.groceries[k].unitPrice * cx.groceries[k].weight); 
     numItems++; 
    } 
    fprintf(wPtr, "---------------------------------------------\n\n"); 
    fprintf(wPtr, "Total\t\t\t\t$%.2f\n\n", total); 
    fprintf(wPtr, "%d items bought\n\n\n\n", numItems); 
} 
0

fopen结果中提到的所有问题,应该进行测试,以避免segfault 想想动态分配内存

速战速决

int main() {                 

    FILE *ptr, *wPtr;               
    int numCustomers, i;              
    ptr = fopen("input.txt","r");            
    wPtr = fopen("invoices.txt","w");           
    /* should be tested */              

    numCustomers = numCust(ptr);            
    customer customerList[numCustomers];          
    memset(customerList, 0, numCustomers * sizeof(customer));     

    for(i = 0; i < numCustomers; i++) {           
     createCustomer(ptr,&(customerList[i]));         
    }                   

    for(i = 0; i < numCustomers; i++) {           
     printInvoice(wPtr,customerList[i]);          
    }                   
    fclose(ptr);                
    fclose(wPtr);                
    return 0;                 
} 

void createCustomer(FILE*ptr,customer *cx) {         
    char tempF[15],tempL[15],k;             

    fscanf(ptr,"%s%s", tempF,tempL);           
    strcpy(cx->fName,tempF);             
    strcpy(cx->lName,tempL);             
    fscanf(ptr,"%d", &(cx->numGroceries));          

    for(k=0;k<cx->numGroceries;k++) {           
     createGroceryList(ptr,&(cx->groceries[k]));        
    }                   
} 

给出此输出

[email protected]:~$ cat invoices.txt 
Customer Name: John Brown 

Cabbage   1.5 @ 2.50  $3.75 

Cucumbers  1.0 @ 3.00  $3.00 

Tomatoes  3.0 @ 1.50  $4.49 

--------------------------------------------- 

Total       $11.24 

3 items bought 



Customer Name: Mary Winters 

Squash 1.5 @ 2.50  $3.70 

Zucchini  2.0 @ 3.50  $6.97 

Watercress  1.3 @ 2.50  $3.22 

Tomatoes  3.0 @ 3.00  $8.97 

--------------------------------------------- 

Total       $22.86 

4 items bought 
相关问题