Reputation: 313
I want to fill an array of char pointers in the following format:
[name, number of email addresses, all the email addresses]*number of people. The number of mail adresses for each person isn't known at first.
This is my main so far:
int main()
{
char *contacts[N];
int nextAvailable = 0;
int * const nextAvailableP = &nextAvailable;
add(contacts, nextAvailableP);
//Printing this way will only print contacts[0]
int i;
for (i = 0; i < nextAvailable; i++) {
printf("%s", contacts[i]);
}
}
This is the add function:
int add(char *contacts[], int *nextAvailableP) {
if (*nextAvailableP > 97) {
printf("Not enough memory\n");
return FALSE;
}
char tempName[50];
char tempMail[50];
int numberOfMails = 1;
printf("Enter your name\n");
fgets(tempName, 50, stdin);
if ((strlen(tempName) > 0) && (tempName[strlen(tempName) - 1] == '\n'))
tempName[strlen(tempName) - 1] = '\0';
contacts[*nextAvailableP] = (char *)malloc((strlen(tempName) + 1));
if (contacts[*nextAvailableP] == NULL) {
printf("Not enough memory\n");
return FALSE;
} else {
strcpy(contacts[*nextAvailableP], tempName);
}
(*nextAvailableP)++;
int numberOfMailsIndex = *nextAvailableP;
itoa(numberOfMails, contacts[numberOfMailsIndex], 10);
(*nextAvailableP)++;
printf("Enter your mail/s, use enter to enter a mail and '-1' to signal you finished\n");
fgets(tempMail, 50, stdin);
while (strcmp(tempMail, "-1") != 0) {
if ((strlen(tempMail) > 0) && (tempMail[strlen(tempMail) - 1] == '\n')) {
tempMail[strlen(tempMail) - 1] = '\0';
}
contacts[*nextAvailableP] = (char *)malloc((strlen(tempMail) + 1));
if (contacts[*nextAvailableP] == NULL) {
printf("Not enough memory");
return FALSE;
} else {
strcpy(contacts[*nextAvailableP], tempMail);
}
(*nextAvailableP)++;
numberOfMails++;
itoa(numberOfMails, contacts[numberOfMailsIndex], 10);
fgets(tempMail, 50, stdin);
}
}
I thought I was initializing each cell in contacts to the requested size and then copying the word I scan from the user into it - but obviously I'm not. Should I iterate through each memory I've allocated char by char?
Btw, I know that the casting to *char isn't necessary
Upvotes: 1
Views: 821
Reputation: 26
So this would be your corrected code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_ENTRIES 50
int add(char *contacts[], int *nextAvailable);
int main(void){
int i;
char *contacts[MAX_ENTRIES];
int nextAvailable = 0;
add(contacts, &nextAvailable);
add(contacts, &nextAvailable);
for(i=0; i < nextAvailable ; i++){
printf("%s\n", contacts[i]);
}
}
char* intToString(int val, int base){
//source: www.strudel.org.uk/itoa/
static char buf[32] = {0};
int i = 30;
for(; val && i ; --i, val /= base)
buf[i] = "0123456789abcdef"[val % base];
return &buf[i+1];
}
int add(char *contacts[], int *nextAvailableP) {
if (*nextAvailableP > 97) {
printf("Not enough memory\n");
return 0;
}
char tempName[50];
char tempMail[50];
int numberOfMails = 1;
printf("Enter your name\n");
fgets(tempName, 50, stdin);
if ((strlen(tempName) > 0) && (tempName[strlen(tempName) - 1] == '\n'))
tempName[strlen(tempName) - 1] = '\0';
contacts[*nextAvailableP] = (char *)malloc((strlen(tempName) + 1));
if (contacts[*nextAvailableP] == NULL) {
printf("Not enough memory\n");
return 0;
} else {
strcpy(contacts[*nextAvailableP], tempName);
}
(*nextAvailableP)++;
int numberOfMailsIndex = (*nextAvailableP);
contacts[numberOfMailsIndex] = malloc(5);
(*nextAvailableP)++;
printf("Enter your mail/s, use enter to enter a mail and '-1' to signal you finished\n");
fgets(tempMail, 50, stdin);
while (strcmp(tempMail, "-1\n") != 0) {
if ((strlen(tempMail) > 0) && (tempMail[strlen(tempMail) - 1] == '\n')) {
tempMail[strlen(tempMail) - 1] = '\0';
}
contacts[*nextAvailableP] = (char *)malloc((strlen(tempMail) + 1));
if (contacts[*nextAvailableP] == NULL) {
printf("Not enough memory");
return 0;
} else {
strcpy(contacts[*nextAvailableP], tempMail);
}
(*nextAvailableP)++;
numberOfMails++;
fgets(tempMail, 50, stdin);
}
strcpy(contacts[numberOfMailsIndex], intToString(numberOfMails - 1,10));
}
Upvotes: 1
Reputation: 26
Your function add could be cut in a subfunction which gets a string from the user. This string will be stored in a allocated memory space which has the size of string.
Keep in mind : It's not a good practice to mix data of different nature in one array (names and email). It would be better to use structs (as @Barmar said).
I would do following steps:
Anyway here's a code that you can start play with:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_ENTRIES 50
#define BUFFERSIZE 50
int add(char *contacts[], int *nextAvailable);
char *getString(char *queryText);
char* intToString(int val, int base);
int main(void){
int i;
char *contacts[MAX_ENTRIES];
int nextAvailable = 0;
add(contacts, &nextAvailable);
add(contacts, &nextAvailable);
for(i=0; i < nextAvailable ; i++){
printf("%s", contacts[i]);
}
}
int add(char *contacts[], int *nextAvailable){
if(*nextAvailable > MAX_ENTRIES - 1){
printf("Not enough memory\n");
return 1;
}
contacts[*nextAvailable] = getString("Enter your name\n");
if(contacts[*nextAvailable] == NULL){
printf("Malloc Error\n");
return 1;
}
++(*nextAvailable);
int counterfield = *nextAvailable;
++(*nextAvailable);
int emailCounter = 0;
while(1){
if(*nextAvailable > MAX_ENTRIES - 1){
printf("Not enough memory\n");
return 1;
}
char *email = getString("Enter email\n");
if(strcmp(email, "-1\n") == 0){
contacts[counterfield] = malloc(5);
contacts[counterfield] = intToString(emailCounter, 10);
return 0;
}
emailCounter++;
contacts[*nextAvailable] = email;
++(*nextAvailable);
}
}
char *getString(char *queryText){
char buffer[BUFFERSIZE];
char *ret;
printf("%s", queryText);
fgets(buffer, BUFFERSIZE, stdin);
ret = malloc(strlen(buffer));
strcpy(ret, buffer);
return ret;
}
char* intToString(int val, int base){
//source: www.strudel.org.uk/itoa/
static char buf[32] = {0};
int i = 30;
for(; val && i ; --i, val /= base)
buf[i] = "0123456789abcdef"[val % base];
return &buf[i+1];
}
Upvotes: 0