C : printf printing variables in the mixed order - c

Here is my code,
#include <time.h>
#include <pthread.h>
#include <string.h>
#include <inttypes.h>
#include <unistd.h>
unsigned sleep(unsigned sec) ;
void get_time(char *buf) {
time_t t = time(NULL) ;
struct tm tm = *localtime(&t) ;
sprintf(buf,"%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec) ;
}
void *calculateSize(uint64_t size, char *buf) {
if (size < 1024ULL){
sprintf(buf, "%.1f %s", (float) size, "B") ;
return NULL ;
}
else if (size < (1024 * 1024)) {
sprintf(buf, "%.1f %s", (float) size/1024ULL, "KiB") ;
return NULL ;
}
else if (size > (1024 * 1024)) {
sprintf(buf, "%.1f %s", (float) size/(1024ULL * 1024ULL), "MiB") ;
return NULL ;
}
strcpy(buf, "0") ;
return NULL ;
}
void * run(char *interface, char * download_buf, char * upload_buf) {
unsigned long rdiff,tdiff ;
unsigned long rx_old,rx_new ;
unsigned long tx_old,tx_new ;
char buf[10] ;
char rx_file[512] ;
char tx_file[512] ;
sprintf(rx_file, "/sys/class/net/%s/statistics/rx_bytes", interface) ;
sprintf(tx_file, "/sys/class/net/%s/statistics/tx_bytes", interface) ;
FILE *rf = fopen(rx_file,"r") ;
FILE *tf = fopen(tx_file,"r") ;
if (rf != NULL && tf != NULL) {
fscanf(rf,"%lu", &rx_old) ;
fscanf(tf,"%lu", &tx_old) ;
fclose(rf) ;
fclose(tf) ;
}
else {
return NULL ;
}
sleep(1) ;
rf = fopen(rx_file,"r") ;
tf = fopen(tx_file,"r") ;
if (rf != NULL && tf != NULL) {
fscanf(rf,"%lu", &rx_new) ;
fscanf(tf,"%lu", &tx_new) ;
rdiff = rx_new - rx_old ;
tdiff = tx_new - tx_old ;
fclose(rf) ;
fclose(tf) ;
}
else {
return NULL ;
}
calculateSize(rdiff,buf) ;
strcpy(download_buf,buf) ;
calculateSize(tdiff,buf) ;
strcpy(upload_buf,buf) ;
return NULL ;
}
void *net_speed(void *thread_speed_args ) {
char* iface = *(char **)thread_speed_args ;
char carrier_file[512] ;
sprintf(carrier_file,"/sys/class/net/%s/carrier", iface) ;
printf("Reading from %s\n", carrier_file) ;
while(1) {
if( access( carrier_file, F_OK ) == 0 ) {
run(iface, ((char **)thread_speed_args)[1], ((char **)thread_speed_args)[2]) ;
}
else {
sprintf(((char **)thread_speed_args)[1],"000 B") ;
sprintf(((char **)thread_speed_args)[2],"000 B") ;
sleep(1) ;
}
}
return NULL ;
}
int main(int argc, char *argv[]) {
char time_buf[10] ; //hh:mm:ss : 8 char + 1 null terminator char
char download_buf[8],upload_buf[8] ;
char* thread_speed_args[3] = { argv[1], download_buf, upload_buf } ;
pthread_t thread_speed ;
pthread_create(&thread_speed, NULL, net_speed, thread_speed_args) ;
pthread_detach(thread_speed) ;
while(1){
get_time(time_buf) ;
printf("Down:%s Up:%s %s\n", thread_speed_args[1], thread_speed_args[2], time_buf) ;
fflush(stdout) ;
sleep(1) ;
}
}
I am using a thread to continuously monitor my wireless data transfer rate on an interface, I am also printing the time along with the transfer rate. I am just experimenting with threads, forgive me if my programming logic is bad.
I notice that when I do a speed test the output or print becomes all messed up like below
Down:0.0 B Up:0.0 B 23:49:03
Down:0.0 B Up:0.0 B 23:49:04
Down:0.0 B Up:0.0 B 23:49:05
Down:17.0 KiB9.2 KiB Up:9.2 KiB 23:49:06
Down:5.3 KiB Up:6.5 KiB 23:49:07
Down:3.4 KiB Up:4.1 KiB 23:49:08
Down:400.6 Ki20.3 KiB23:49:09 Up:20.3 KiB23:49:09 23:49:09
Down:918.6 Ki49.6 KiB23:49:10 Up:49.6 KiB23:49:10 23:49:10
Down:912.8 Ki53.5 KiB23:49:11 Up:53.5 KiB23:49:11 23:49:11
Down:959.2 Ki32.2 KiB23:49:12 Up:32.2 KiB23:49:12 23:49:12
Down:711.5 Ki33.8 KiB23:49:13 Up:33.8 KiB23:49:13 23:49:13
See the last few lines?
Could anyone tell me what is happening here? How do I correct it?

This is happening because you're accessing a common resource in multiple threads simultaneously - in this case, the STDOUT handle. You'll need to synchronize your threads when outputting the information to the console - the easiest way is using mutexes. You can read more here.

While your threads lack any kind of synchonization (which will randomly garble your output in some rare cases) this isn't even your problem.
Here is your problem:
char download_buf[8],upload_buf[8] ;
char buf[10] ;
strcpy(download_buf,buf) ;
strcpy(upload_buf,buf) ;
You are copying an up to 9 character string into a 7 char string so that overflows the buffer. And since the buffers happen to be next to each other on the stack the second strcpy will overwrite the 0 terminator of the first string. Same with the time_buf overwriting the 0 terminator of the second string.
Overall a whole lot of undefined behavior due to buffer overflows.

Related

Make function to read Temperature from DS18B20 and show on LCD

I want to create a new function that will return me a actual temperature from DS18B20 as a float variable. I need that kind of variable to place a string on LCD.
Already I'm using function to read temperature like that:
int8_t readTemp(struct ds18b20 *d) {
struct ds18b20 *newTemp;
char tempAct[5];
while (d->next != NULL)
{
d = d->next;
int fd = open(d->devPath, O_RDONLY);
if (fd == -1)
{
perror("Couldn't open the w1 device.");
return 1;
}
char buf[256];
ssize_t numRead;
while ((numRead = read(fd, buf, 256)) > 0)
{
newTemp = malloc(sizeof(struct ds18b20));
strncpy(newTemp->tempData, strstr(buf, "t=") + 2, 5);
//float tempC = strtof(d->tempData, NULL);
sprintf(tempAct, "%s C", newTemp->tempData);
//printf("Device: %s - ", d->devID);
//printf("Temp: %.3f C ", tempC / 1000);
//printf("%.3f F\n\n", (tempC / 1000) * 9 / 5 + 32);
}
close(fd);
}
return 1;}
I have problem with sprintf from this line:
sprintf(tempAct, "%s C", newTemp->tempData);
In the main code:
int main(void) {
struct ds18b20 *rootNode;
struct ds18b20 *devNode;
struct ds18b20 *getTemp;
// Load pin configuration. Ignore error if already loaded
system("echo w1 > /sys/devices/bone_capemgr.9/slots>/dev/null");
while (1) {
rootNode = malloc(sizeof(struct ds18b20));
devNode = rootNode;
getTemp = rootNode;
int8_t devCnt = findDevices(devNode);
printf("\n Found %d devices\n\n", devCnt);
int8_t tempAct = readTemp(getTemp);
printf("\n Temp Act: %d \n\n", tempAct);
//readTemp(rootNode);
// Free linked list memory
while (rootNode) {
// Start with current value of root node
devNode = rootNode;
// Save address of next devNode to rootNode before deleting current devNode
rootNode = devNode->next;
// Free current devNode.
free(devNode);
}
free(rootNode);
}
return 0;}
I'm trying to recreate the functions from finddevices:
int8_t devCnt = findDevices(devNode);
printf("\n Found %d devices\n\n", devCnt);
int8_t tempAct = readTemp(getTemp);
printf("\n Temp Act: %d \n\n", tempAct);
But the tempData* isn't imported from readTemp fuction to main code.
The code is littered with issues that are not explicitly part of your question. Just some:
readTemp() does not return temperature. In fact it returns 1 if it fails and 1 if it succeeds. That is probably an error.
readTemp() appears to read all available temperature sensors, passed to it as a linked list of struct ds18b20 not just one. But actually skips the root node and accesses the second and subsequent without checking it is valid. If the root node contains no device (just a pointer to the first device), then you need only pass it pass rootNode->next instead.
It is not clear why it dynamically allocates a new struct ds18b20 or why it fails to later de-allocate. That is a serious memory leak.
At a guess the following is more likely to be close to what you need (without knowing anything about struct ds18b20 or what the expected output of the sensor is - just going by the evidence in the code (and commented out code) you have posted - so some bold assumptions have been made.
int readTemp( struct ds18b20 *d, // List of sensors
float* temperatures, // Pointer to array to receive temperatures
int8_t max_temperatures ) // Max number of temperatures to receive
{
struct ds18b20* sensor = d ;
int count = 0 ;
while( sensor != NULL && count < max_temperatures )
{
int fd = open( sensor->devPath, O_RDONLY ) ;
if( fd >= 0 )
{
if( read( fd, buf, sizeof(buf) ) > 0 )
{
char buf[256];
char* temp_str = strstr(buf, "t=") + 2 ;
sscanf( temp_str, "%f", &temperatures[count] ) ;
temperatures[count] /= 1000 ;
count++ ;
}
close( fd ) ;
sensor = sensor->next ;
}
else
{
perror("Couldn't open the w1 device.");
}
}
return count ;
}
Then in you can call it thus:
int8_t devCount = findDevices( rootNode ) ;
float* temperatures = malloc( devCnt * sizeof(float) ) ;
int8_t tempCount = readTemp( rootNode->next, temperatures, devCount ) ;
for( int i = 0; i < tempCount; i++ )
{
printf( "Temp Act: %f\n", temperatures[i] ) ;
}
free( temperatures ) ;
If you know there is only one device or you only need print the first, then this can be simplified:
int8_t devCount = findDevices( rootNode ) ;
if( devCount > 0 )
{
float temperature = 0f ;
int8_t tempCount = readTemp( rootNode->next, temperature, 1 ) ;
if( tempCount > 0 )
{
printf( "Temp Act: %f\n", temperature ) ;
}
}
Issues in your main() are also varied, including:
The root node is needlessly dynamically allocated
several aliases to the root node are needlessly created
The device list is repeatedly re-enumerated and the device list allocated and free'd on every iteration of a non-terminating loop. Assuming the number of sensors does not change while the code is running, this is unnecessary.
The loop never ends - even in the event of an error.
A better implementation might look something like:
int main(void)
{
// Load pin configuration. Ignore error if already loaded
system("echo w1 > /sys/devices/bone_capemgr.9/slots>/dev/null");
struct ds18b20 rootNode = { 0 } ;
int8_t devCount = findDevices( rootNode ) ;
if( devCount > 0)
{
struct ds18b20* devlist = rootNode->next ;
float* temperatures = malloc( devCount * sizeof(float) ) ;
int8_t tempCount = 0 ;
do
{
tempCount = readTemp( devList, temperatures, devCount ) ;
for( int i = 0; i < tempCount; i++ )
{
printf( "Temp Act: %f\n", temperatures[i] ) ;
}
} while (tempCount > 0 ) ;
// Free resources after a temperature read fails
free( temperatures ) ;
// Free linked list memory
while( devlist != NULL )
{
// Save address of next before deleting current
struct ds18b20* next = devlist->next ;
// Free current devNode.
free( devlist ) ;
// get next
devlist = next ;
}
}
return 0 ;
}

How to define multiple streams from UARTs to be used in fprintf

I'm working with ARM (SAM4), it has two UARTs, I need to setup streams so that I could use fprintf to print on both.
Already tried fwopen without luck:
FILE * debug;
debug_writefn(void *cookie, const char *buf, int n);
void comm_init(void) {
debug = fwopen(NULL, &debug_writefn);
if (debug == NULL) {
printf("Error");
}
fprintf(debug, "Test");
}
However, the debug_writefn is newer called.
I'm using the arm-none-eabi-* toolchain (I guess it uses newlib), ASF and FreeRTOS.
You only need re-implement newlib's _write() or write_r() syscall to handle the stdout the stream file handle in any way you require, e.g.:
enum
{
STDIN_HANDLE,
STDOUT_HANDLE,
STDERR_HANDLE
} ;
long _write( int fd, const void *buf, size_t cnt )
{
int ret = EOF ;
if( fd == STDOUT_HANDLE || fd == STDERR_HANDLE )
{
for( int i = 0; i < cnt; i++ )
{
serialPutc( UART1, buf[i] ) ;
serialPutc( UART2, buf[i] ) ;
}
ret = i ;
}
return ret ;
}

Data base confusion

I have a strange thing in my code execution
every thing goes ok except the value of player_count. When i read the data again from file, it still = 0 although name and email are updated correctly ..!!
why player_count still equal 0 ??????
here is the code :
#define MAX_DATA 128
#define STRLEN 101
#define FILENAME "C:\\Users\\ahmed\\Desktop\\C codes\\new_game\\data_base.dat"
typedef struct
{
char name[STRLEN] ;
char email[STRLEN] ;
int score ;
int id ;
int Set ;
} player_t ;
typedef struct
{
player_t player[MAX_DATA] ;
int player_count ;
}DataBase ;
typedef struct
{
DataBase db ;
FILE *filename ;
}Connection ;
void Store_Player_Database( int score )
{
Connection *conn = Creat_Connection(FILENAME );
player_t *player = conn->db.player ;
Read_Database(conn) ;
int player_num = conn->db.player_count ;
printf("Your name : ") ;
get_str(player[player_num].name , STRLEN) ;
printf("Your e-mail : ") ;
get_str(player[player_num].email , STRLEN) ;
player[player_num].Set = 1 ;
player[player_num].score = score ;
conn->db.player_count++ ;
printf("count here = %d\n",conn->db.player_count) ;
Write_Database(conn) ;
}
Connection *Creat_Connection(const char *filename )
{
Connection *conn = calloc(1,sizeof(Connection)) ;
//check_mem(conn) ;
int i = 0;
for( i = 0 ; i< MAX_DATA ; i++)
conn->db.player[i].id = i+1 ;
/// for update or read
conn->filename = fopen(filename , "r+") ;
//check(db->filename , "File open failed !") ;
return conn ;
}
int Read_Database(Connection *conn)
{
int rc ;
if(conn)
{
if(conn->filename)
{
DataBase *db = &conn->db ;
rc=fread(db,sizeof(DataBase),1,conn->filename); // load database from file .
printf("count = %d\n" , db->player_count) ;printf("%s %s \n" , db->player[0].name , db->player[0].email);
/* if (rc != 1)
{
printf("Error load database from file\n") ;
return -1 ;
}*/
}
}
return 1 ;
}
int Write_Database(Connection *conn)
{
int rc ;
if(conn)
{
if(conn->filename)
{
rewind(conn->filename) ;
DataBase *db = &conn->db ;printf("%s %s count = %d \n" , db->player[0].name , db->player[0].email , conn->db.player_count);
rc = fwrite(db,sizeof(DataBase),1,conn->filename) ;
if (rc != 1)
{
printf("Error load database from file\n") ;
return -1 ;
}
fflush(conn->filename) ;
}
}
return 1 ;
}
/*****************************/
int main(void)
{
int score = 5 ;
/* any code here */
Store_Player_Database(score) ;
Store_Player_Database(score +1) ; // at that call i get name and mail correct but player_count still zero ??? why?!
return 0 ;
}
When i try this program in linux it runs correctly
then i find the bug finally .
In windows fread should open in binary mode like that :
conn->filename = fopen(filename , "rb+") ; // use rb+ instead of r+ to open it in binary mode

Converting hexadecimal to ASCII in c

I'm working on an Android rom for a mobile phone and I want to make the kernel load the wifi MAC address from the device's NV partition. My code looks like this:
#include <linux/kernel.h>
#include <linux/random.h>
#include <linux/syscalls.h>
#define ETHER_ADDR_LEN 6
#define FILE_WIFI_MACADDR "/dev/block/mmcblk0p7"
static int bcm_wifi_get_mac_addr(unsigned char *buf)
{
int ret = 0;
mm_segment_t oldfs;
int i;
int fp;
int macbyte;
int readlen = 0;
uint rand_mac;
static unsigned char mymac[ETHER_ADDR_LEN] = {0,};
const unsigned char nullmac[ETHER_ADDR_LEN] = {0,};
const unsigned char bcastmac[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
if (buf == NULL)
return -EAGAIN;
memset(buf, 0x00, ETHER_ADDR_LEN);
oldfs = get_fs();
set_fs(get_ds());
fp = sys_open(FILE_WIFI_MACADDR, O_RDONLY, 0);
if (fp < 0) {
pr_err("%s: Failed to read error %d for %s\n",
__FUNCTION__, fp, FILE_WIFI_MACADDR);
goto random_mac;
}
for (i = 0; i<12; i++) {
macbyte=0;
sys_lseek( fp,i+7680,SEEK_SET);
readlen = sys_read(fp,&macbyte,1);
if (i)
sprintf(macaddr,"%s%c",macaddr,macbyte);
else
sprintf(macaddr,"%c",macbyte);
}
if (readlen > 0) {
unsigned char* macbin;
macbin = (unsigned char*)macaddr;
pr_info("%s: READ MAC ADDRESS %02X:%02X:%02X:%02X:%02X:%02X\n",
__FUNCTION__,
macbin[0], macbin[1], macbin[2],
macbin[3], macbin[4], macbin[5]);
if (memcmp(macbin, nullmac, ETHER_ADDR_LEN) == 0 ||
memcmp(macbin, bcastmac, ETHER_ADDR_LEN) == 0) {
sys_close(fp);
goto random_mac;
}
memcpy(buf, macbin, ETHER_ADDR_LEN);
} else {
sys_close(fp);
goto random_mac;
}
sys_close(fp);
return ret;
random_mac:
set_fs(oldfs);
pr_debug("%s: %p\n", __func__, buf);
if (memcmp( mymac, nullmac, ETHER_ADDR_LEN) != 0) {
/* Mac displayed from UI is never updated..
So, mac obtained on initial time is used */
memcpy(buf, mymac, ETHER_ADDR_LEN);
return 0;
}
srandom32((uint)jiffies);
rand_mac = random32();
buf[0] = 0x00;
buf[1] = 0x90;
buf[2] = 0x4c;
buf[3] = (unsigned char)rand_mac;
buf[4] = (unsigned char)(rand_mac >> 8);
buf[5] = (unsigned char)(rand_mac >> 16);
memcpy(mymac, buf, 6);
pr_info("[%s] Exiting. MAC %02X:%02X:%02X:%02X:%02X:%02X\n",
__FUNCTION__,
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5] );
return 0;
}
The idea is to load the nv parition, located at /dev/block/mmcblk0p7, then read the mac address, which is located at offset 7680 on the nv. The problem is that the MAC address is written in hex, so I'm trying to print it to an ASCII string using sprintf().
for (i = 0; i<12; i++) {
macbyte=0;
sys_lseek( fp,i+7680,SEEK_SET);
readlen = sys_read(fp,&macbyte,1);
if (i)
sprintf(macaddr,"%s%c",macaddr,macbyte);
else
sprintf(macaddr,"%c",macbyte);
}
In the nv the MAC looks something like this: 34 30 42 30 46 41 36 35 39 33 34 39, which in ASCII is 40B0FA659349. But instead the resulting MAC is 34:30:42:30:46:41, which tells me that the hex values are not getting converted at all.
What would be the proper way to export the hex values into an ASCII string? I'm new to programming and i was hoping someone could give me some tips.
Thanks in advance.
In your loop you are reading single bytes and converting them to hex strings, while what you actually need to do is read the hex string and convert it byte values. Unless you actually want a hex string, in which case no conversion is necessary.
You have 12 hex characters representing 6 bytes so:
#define MAC_LEN 6
uint8_t macbytes[MAC_LEN] ;
for( i = 0; i < MAC_LEN; i++ )
{
char hex_str[3] ;
unsigned byte_val ;
sys_lseek( fp, (i*2) + 7680, SEEK_SET ) ;
readlen = sys_read( fp, hex_str, 2 ) ;
sscanf( hex_str, "%2X", &byte_val ) ;
macbytes[i] = (uint8_t)byte_val ) ;
}
The data in NV is already ASCII coded hexadecimal; for example 0x34 is the ASCII code for the hex digit '4', and 0x30 that for '0', together the ASCII character pair "40" represent the single 8 bit integer value 0x40. So the conversion you need is ASCII to byte array, not "hex to ASCII" (which makes no semantic sense).
I think this is OP's stubbing block: forming a string version of the MAC address.
I'll make this wiki for anyone to modify, borrow or steal.
sys_lseek( fp,i+7680,SEEK_SET);
char macaddr[100];
char *p = macaddr;
const char *sep = "";
for (i = 0; i < 12; i++) {
unsigned char macbyte;
int readlen = sys_read(fp, &macbyte, 1);
if (readlen != 1) Handle_Error();
p += sprintf(p, "%s%02X", sep, macbyte);
sep = ":";
}
puts(macaddr);

How do I pass an array of Pointers to a structure and allocate the members

ok, heres my code. I'm trying to pass an array of pointers to a structure to a function.
I need to dynamically allocate each structure and put a pointer to that structure in the array.
When I malloc the second time thru it gets a heap error.
HELP
#define MAXSTRUCTS 50
#define MAXBUFF 100
typedef struct {
char fullName[41];
char address[41];
char cityState[41];
char zipcode[11];
} Persons;
int readData(Persons *structPtrs[]);
int main(void) {
int totalStructs;
Persons *structPtrs[MAXSTRUCTS];
totalStructs = 0;
structPtrs[0] = NULL;
totalStructs = readData(structPtrs);
}
int readData(Persons *strptr[]) {
int tStructs = 0;
int recs;
char inRecord[MAXBUFF];
Persons *tmpPtr;
tStructs = 0;
for (recs=0; recs < MAXSTRUCTS; recs++) {
if (gets(inRecord) != NULL) {
strptr[recs] = (Persons *)malloc( sizeof(Persons));
tmpPtr = strptr[recs];
strncpy(tmpPtr->fullName,inRecord,MAXBUFF);
gets(inRecord);
strncpy(tmpPtr->address,inRecord,MAXBUFF);
gets(inRecord);
strncpy(tmpPtr->cityState,inRecord,MAXBUFF);
gets(inRecord);
strncpy(tmpPtr->zipcode,inRecord,MAXBUFF);
strptr[recs] = tmpPtr;
tStructs++;
}
else {
if ( recs = 0 ) {
exit (0);
}
recs=MAXSTRUCTS;
}
}
return(tStructs);
}
You are doing everything right in regard of passing an array of pointers and allocating memory. What leading to a heap corruption is incorrect usage of strncpy function. The arrays where you are trying to copy data to are slightly smaller than MAXBUFF in all cases. To fix this, you have to specify the size of destination array instead of MAXBUFF. For example, instead of:
strncpy(tmpPtr->fullName,inRecord,MAXBUFF);
... do (assuming that buffer is already filled with \0 symbols):
strncpy(tmpPtr->fullName,inRecord, sizeof(tmpPtr->fullName) - 1);
Also, using gets function is not recommended as well as it could easily lead to buffer overruns. Try using fgets instead.
Here is your modified example that works:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define MAXSTRUCTS 2
#define MAXBUFF 100
typedef struct {
char fullName[41];
char address[41];
char cityState[41];
char zipcode[11];
} Persons;
int readData(Persons *structPtrs[]);
int main ()
{
int totalStructs;
int recs;
Persons *structPtrs[MAXSTRUCTS];
totalStructs = 0;
structPtrs[0] = NULL;
totalStructs = readData(structPtrs);
for(recs = 0; recs < totalStructs; ++recs) {
printf ("Record #%d - %s\n", recs + 1, structPtrs[recs]->fullName);
}
return 0;
}
int readData(Persons *strptr[])
{
int tStructs = 0;
int recs;
char inRecord[MAXBUFF];
Persons *tmpPtr;
tStructs = 0;
for (recs=0; recs < MAXSTRUCTS; ++recs) {
memset (inRecord, 0, sizeof(inRecord));
if (fgets(inRecord, sizeof (inRecord) - 1, stdin))
{
strptr[recs] = (Persons *)malloc(sizeof(Persons));
tmpPtr = strptr[recs];
memset (tmpPtr, 0, sizeof(Persons));
strncpy(tmpPtr->fullName,inRecord,sizeof(tmpPtr->fullName) - 1);
fgets(inRecord, sizeof (inRecord) - 1, stdin);
strncpy(tmpPtr->address,inRecord,sizeof(tmpPtr->address) - 1);
fgets(inRecord, sizeof (inRecord) - 1, stdin);
strncpy(tmpPtr->cityState,inRecord, sizeof(tmpPtr->cityState) - 1);
fgets(inRecord, sizeof (inRecord) - 1, stdin);
strncpy(tmpPtr->zipcode,inRecord, sizeof (tmpPtr->zipcode) - 1);
strptr[recs] = tmpPtr;
tStructs++;
} else {
if ( recs = 0 ) {
exit (0);
}
recs=MAXSTRUCTS;
}
}
return(tStructs);
}
int readDataToRecord( Persons *eachEntry[] ) {
int numEntries = 0 ;
Persons *tempPtr ;
for( int i=0 ; i < NUM_OF_RECORDS; ++i ) {
eachEntry[i] = ( Record * ) malloc( sizeof( Record ) ) ;
memset( eachEntry[i], 0, sizeof( Record ) ) ;
tempPtr = eachEntry[i] ;
fgets( tempPtr->firstName, sizeof( tempPtr->firstName ), stdin ) ;
fgets( tempPtr->secondName, sizeof( tempPtr->secondName), stdin ) ;
eachEntry[i] = tempPtr ;
++numEntries ;
}
return numEntries ;
}
This would also efficiently do the job. Once you have new record, you would any how have the memory allocated for each of its member. So you can directly fgets to that variable.
#Vlad : Please let me know if I am wrong.

Resources