This block of code will compile, but gives me a runtime error:

before the first comment is a header that is included in the file that you may need to analyze my code.

typedef char *string;
typedef struct
{
 
     string fieldName;
     string value;
 
}oneField;
 
/* this starts the function*/
 
link tokenize (string input_string)
{
int numOfSpaces;
string next, temp;
oneField thisRecord;
/* used for head of linked list */
link head;
int field, counter = 0;
void insert(link*, oneField);
head = 0;
while(1)
{
numOfSpaces = 0;
next = next_word(input_string, &numOfSpaces);
/* next = the word which we will work with here */
if(counter == 0){
strcpy(thisRecord.fieldName, next);
}
if(counter == 1){
strcpy(thisRecord.value, next);
} 
 
/* if the word returned by next_word was the last word
in the input string, then the element at that length
should be the null character, in which case we will
break from the loop */
counter++;
if(input_string[strlen(next)] == '\0')
break;
input_string += strlen(next) + numOfSpaces;
}
return head;
}

If I comment out the strcpy methods, it will run fine, but for some reason it will not copy the value of the string into the struct. Any help would be greatly appreciated.

Reguards,

Tyler S. Breton

Recommended Answers

All 4 Replies

Why are you using the strcpy function? These are C++ strings. Use the = operator.

thisRecord.fieldName =next

No, this is a C program. string is defined as a char* up top.

PS. I figured out the problem. Thanks

Good. Mind posting the solution so that someone else can learn from it?
Thank you.

Good. Mind posting the solution so that someone else can learn from it?
Thank you.

/**************************
* cgilib.h *
***************************/
typedef char *string;
typedef struct
{
 string fieldName;
 string value;
}oneField;
struct element {
 oneField       data;
 struct element *next;
};
typedef struct element   node;
typedef node             *link;
link tokenize(string input_string);
string cgi_val(link head, string field);
void print_table(link head);
string next_word(char *, int *);
 
 
 
/**************************
* cgilib.c *
***************************/
#include "cgilib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
 *  Used to parse an input string, and returns a linked
 *  list of tokens.  Maintained by alphabetical order of
 *  the field name, and the data stored in each node
 *  is a record representing one field
 */
link tokenize (string input_string)
{
 int numOfSpaces;
 string next;
 oneField thisRecord;
 /* used for head of linked list */
 link head;
 int counter = 0;
 void insert(link*, oneField);
 head = 0;
 while(1)
 {
  numOfSpaces = 0;
  next = next_word(input_string, &numOfSpaces);
  /* next = the word which we will work with here */
  if(counter == 0){
   thisRecord.fieldName = (char *) calloc(strlen(next), sizeof(char));
   strcpy(thisRecord.fieldName, next);
  }else if(counter == 1){
   thisRecord.value = (char *) calloc(strlen(next), sizeof(char));
   strcpy(thisRecord.value, next);
   insert(&head, thisRecord);
  }else if(counter % 2 == 0){
   thisRecord.fieldName = (char *) calloc(strlen(next), sizeof(char));
   strcpy(thisRecord.fieldName, next);
  }else{
   thisRecord.value = (char *) calloc(strlen(next), sizeof(char));
   strcpy(thisRecord.value, next);
   insert(&head, thisRecord);
  }
  /* if the word returned by next_word was the last word
     in the input string, then the element at that length
     should be the null character, in which case we will
     break from the loop */
  counter++;
  if(input_string[strlen(next)] == '\0')
   break;
  input_string += strlen(next) + numOfSpaces;
 }
 return head;
}
/*
 *  Steps through the linked list pointed to by the head
 *  and finds the node pointed to by the given field
 */
string cgi_val(link head, string field)
{
 void toUpper(string);
 link start = head;
 while(head)
 {
  toUpper(head->data.fieldName);
  toUpper(field);
  if(!strcmp(head->data.fieldName, field))
  {
   return head->data.value;
  }
  head = head->next;
 }
 head = start;
 return "ERROR!  FIELD NAME NOT FOUND!";
}
/*
 *  Used to print the table
 *  Given: head of linked list
 */
void print_table(link head)
{
 link start = head;
 printf("\n%s%26s\n%s\n", "Field Name", "Value", 
     "----------------------------------------------");
 while(head)
 {
  printf("%-20s%-40s\n", head->data.fieldName, head->data.value);
  head = head -> next;
 }
 printf("----------------------------------------------\n");
 head = start;
}
/*  
 *  Used in order to put strings of any length in
 *  the linked list (dynamically generates the string)
 */
string next_word(char * pos, int *numOfSpaces){
 /* count is the number of total characters in the string,
    whereas trueCount counts special 3-digit characters as
    only one 'true' character*/
 int count = 0, trueCount = 0, i;
 char * b = pos;
 int forConvert;
 string a;
 char current;
 if(pos[0] == '\0')
  return NULL;
 /* still check for spec. char in input */
 while(((current = *b) != '=') && (current != '&') && (current != '\0')){
  trueCount++;
  count++;
  b++;
  if(current == '%')
   trueCount = trueCount - 2;
 }
 a = (char *) calloc(trueCount + 1, sizeof(char));
 /* check for spec chars */
 for(i = 0; i < trueCount; i++)
 {
  if(*pos == '%')
  {
   pos++;
   switch(*pos)
   {
    case '0': forConvert = 16*0;
         break;
    case '1': forConvert = 16*1;
         break;
    case '2': forConvert = 16*2;
         break;
    case '3': forConvert = 16*3;
         break;
    case '4': forConvert = 16*4;
         break;
    case '5': forConvert = 16*5;
         break;
    case '6': forConvert = 16*6;
         break;
    case '7': forConvert = 16*7;
         break;
    case '8': forConvert = 16*8;
         break;
    case '9': forConvert = 16*9;
         break;
    case 'A':
    case 'a': forConvert = 16*10;
         break;
    case 'B': 
    case 'b': forConvert = 16*11;
         break;
    case 'C':
    case 'c': forConvert = 16*12;
         break;
    case 'D':
    case 'd': forConvert = 16*13;
         break;
    case 'E':
    case 'e': forConvert = 16*14;
         break;
    case 'F':
    case 'f': forConvert = 16*15;
         break;
    default:
      printf("%c is not a proper hex number!\n", *pos);
      exit(1);
   }
   pos++;
   switch(*pos)
   {
    case '0': forConvert += 0;
         break;
    case '1': forConvert += 1;
         break;
    case '2': forConvert += 2;
         break;
    case '3': forConvert += 3;
         break;
    case '4': forConvert += 4;
         break;
    case '5': forConvert += 5;
         break;
    case '6': forConvert += 6;
         break;
    case '7': forConvert += 7;
         break;
    case '8': forConvert += 8;
         break;
    case '9': forConvert += 9;
         break;
    case 'A':
    case 'a': forConvert += 10;
         break;
    case 'B': 
    case 'b': forConvert += 11;
         break;
    case 'C':
    case 'c': forConvert += 12;
         break;
    case 'D':
    case 'd': forConvert += 13;
         break;
    case 'E':
    case 'e': forConvert += 14;
         break;
    case 'F':
    case 'f': forConvert += 15;
         break;
    default:
      printf("%c is not a proper hex number!(2)\n", *pos);
      exit(1);
   }
   *numOfSpaces = *numOfSpaces + 2;
   a[i] = forConvert;
  }else if(*pos == '+'){
   a[i] = ' ';
  }else{
   a[i] = *pos;
  }
  pos++;
 }
 a[trueCount] = '\0';
 *numOfSpaces = *numOfSpaces + 1;
 return a;
}

/***************************************************
****************************************************
****************************************************
***************************************************/
void insert(link *list_head, oneField a){
 link p = *list_head, prev = NULL, new_node;
 while(p && strcmp(a.fieldName, p->data.fieldName) > 0)
 {
  prev = p;
  p = p->next;
 }
 new_node = malloc(sizeof(node));
 new_node -> data = a;
 new_node -> next = p;
 if(prev)
  prev -> next = new_node;
 else
  *list_head = new_node;
}
void toUpper(string a){
 int i;
 
 for(i = 0; i < strlen(a); i++){
  a[i] = toupper(a[i]);
 }
}
 
 
/**************************
* mainProgram.c *
***************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cgilib.h"  /*  It contains the function prototype of
                           "exit".  */
string get_input(void)
{
 string a;
 int c;
 int count = 0;
 char file_name[20];
 FILE *text;
 printf("\n\nEnter the file name -->  ");
 gets(file_name);
 text = fopen(file_name, "r");  /*  open the file for reading  */
 if (!text)
 {
  printf("\n\nError: The file \"%s\" does not exist.\n",
                                       file_name);
  exit(1);        /*  terminate the program with an error  */
 }

 while ((c = getc(text)) != EOF)
  count++;
        
 fclose(text);
 a = (char *)calloc(count+1, sizeof(char));
 text = fopen(file_name, "r");
 if(!text)
 {
  printf("file not found!!!!\n");
  exit(1);
 }
 fgets(a, count+1, text);
 return a;
}
void main()
{
 link a;
 char inputField[31];
 string inputString;
 inputString = get_input();
 a = tokenize(inputString);
 print_table(a);
 while(1){
  printf("Enter a field name(Enter exit to Quit): ");
  gets(inputField);
  if(!strcmp(inputField, "exit")){
   break;
  }
  printf("Value for specified field: %s\n", cgi_val(a,inputField));
 }
}

Sorry for the tabbing problem, my text editor didnt include the tabs correctly when I pasted.
I realize there is a memory leak in the cgiscript.c file, I didnt free the space allocated, but the program compiles and runs successfully. Oh, and just so you know, this is a cgiscript file which reads in a cgiscript from a txt file and parse's it into its correct components.

commented: Thx +5
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.