简体   繁体   中英

pointer that is assigned value in function is blank after returning

Making a function for adding a customer record on to a text file. I have made a function that would trim leading and last spaces off customer name etc, called trimspaces.

the function addrecord is to handle storing of record in file. It gets given 3 parameters (name /address/ phone). Before storing operation function will remove whitespaces using trimspaces function, then combine the 3 strings to one.

#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h> //mkdir
#include <stdio.h> //printf
#include <errno.h> //error number
#include <unistd.h> //access
#include <string.h> //strcat
#include <ctype.h> //isspace
#include <stdlib.h>//malloc

int checkFile();
int makeFile();
int addRecord(char* name, char* addr, char* phon);
int searchRec(int column, char* value);
char* getRec(int recNo);
int getRecNo();
char* trimspaces(char* string,char*ptr);


int addRecord(char* name, char* addr, char* phon){
    printf("\n- starting records addReord function -\n");   
    int success = 0;

    char* namt = trimspaces(name,namt);
    char* addt = trimspaces(addr,addt);
    char* phot = trimspaces(phon,phot);

    //this prints "trimmed words: , , " 
    printf("\n trimmed words: %s, %s, %s",namt,addt,phot);  


    /*
    char*combined1 = strcat(namt,"|");
    char*combined2 = strcat(combined1,addt);
    char*combined3 = strcat(combined2,"|");
    char*combined4 = strcat(combined3,phot);

    printf("\nwords combined: %s",combined4);

    */

    printf("\n- leaving records addrecord function -\n");
    return success;
}



char* trimspaces(char* string,char*ptr){
    printf("\n- entered trimspaces function -");    

    char *str= string;
    int slen = strlen(str); //string length
    int ctfor = 0; //counter forward
    int ctbak = 0; //counter back

    while(isspace(*str)){ str++; ctfor++; }; //count to start of word
    while(*str){str++;}; //go to end

    do{ str--; ctbak++; }while(isspace(*str)); //count from end to end of word

    int cbako = (slen - ctbak) + 1; //counter back reversed
    int wlen = cbako - ctfor; //get word length

    printf("\nstr_len:%d,counter_fore:%d,counter_bak:%d,cbakreversed:%d,wlen:%d",slen,ctfor,ctbak,cbako,wlen);  

    while(*str){ str--; }
    str++;

    while(isspace(*str)){
        str++; 
    }





    char newStr[wlen]; //char pointer gives segmentation fault
    memcpy(newStr,str,wlen);
    printf("\n--%s--",newStr);

    ptr = malloc(sizeof(newStr)+1);
    ptr = newStr;
    printf("\nPTR is : %s",ptr);

    return ptr;
    printf("\n- leaving trimspaces function -");
}


int main(){
    addRecord("kara","19,sams st","993328");

}

THIS IS THE OUTPUT: (I want the text between --text-- to be string with leading/end spaces remvoed, and timmed words lines to say - TRIMMED words: kara,19,sams st,993328)

- starting records addReord function -

- entered trimspaces function -
str_len:4,counter_fore:0,counter_bak:1,cbakreversed:4,wlen:4
--kara--
PTR is : kara
- entered trimspaces function -
str_len:10,counter_fore:0,counter_bak:1,cbakreversed:10,wlen:10
--19,sams st@--
PTR is : 19,sams st@
- entered trimspaces function -
str_len:6,counter_fore:0,counter_bak:1,cbakreversed:6,wlen:6
@--93328s W
@TR is : 993328s W
 TRIMMED words: , , 
- leaving records addrecord function -

Ive met 2 problems in the output of main function. first the printed string at - printf("\\n TRIMMED words: %s, %s, %s",namt,addt,phot); reads : TRIMMED words: , , Ive tried a number of things but the returned variables are always blank. I wonder if Im using malloc and pointers right.

second problem is

--19,sams st@--
PTR is : 19,sams st@
@--93328s W
@TR is : 993328s W

I dont know where the @ and Ws come from. When I tested trimspaces function with different values it printed correct results.

I will note here that I used export PS1='\\u@\\h: ' on terminal for a shorter prompt.

what should I do to get the variables to print values?

Based on the feedback given Ive modified the code to correct some of the mistakes. this code may not be quite proper and there are still problems(apparently blank inputs strings to trimspaces function gives errors - Im leaving this problem alone and moving on for the moment)

after some digging I found that you need to pass a pointer to a pointer (**) for malloc to work on the variable passed to a different function. still dont understand these principles well but it seems to work. also use strcat on pointer space and char array instead of use of direct = operator.

#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h> //mkdir
#include <stdio.h> //printf
#include <errno.h> //error number
#include <unistd.h> //access
#include <string.h> //strcat
#include <ctype.h> //isspace
#include <stdlib.h>//malloc

int addRecord(char* name, char* addr, char* phon);
void trimspaces(char* string,char**ptr);



int addRecord(char* name, char* addr, char* phon){
    printf("\n- starting records addReord function -\n");   
    int success = 0;

    char* namt = "";
    trimspaces(name,&namt);
    char* addt = "";
    trimspaces(addr,&addt);
    char* phot = "";
    trimspaces(phon,&phot);

    //this prints "trimmed words: , , " 
    printf("\n TRIMMED words: %s, %s, %s",namt,addt,phot);  

    printf("\n- leaving records addrecord function -\n");
    return success;
}



void trimspaces(char* string, char** ptr){
    printf("\n- entered trimspaces function -");    
    //PROBLEMS WITH 0 SIZE OR BLANK INPUT

    char *str= string;
    int slen = strlen(str); //string length
    int ctfor = 0; //counter forward
    int ctbak = 0; //counter back

    while(isspace((unsigned char)*str)){ str++; ctfor++; }; //count to start of word
    while(*str){str++;}; //go to end

    //unsigned char
    do{ str--; ctbak++; }while(isspace((unsigned char)*str)); //count from end to end of word

    int cbako = (slen - ctbak) + 1; //counter back reversed
    int wlen = cbako - ctfor; //get word length

    printf("\nstr_len:%d,counter_fore:%d,counter_bak:%d,cbakreversed:%d,wlen:%d",slen,ctfor,ctbak,cbako,wlen);  

    while(*str){ str--; }
    str++;

    while(isspace((unsigned char)*str)){
        str++; 
    }





    char newStr[wlen+1]; //char pointer gives segmentation fault
    memcpy(newStr,str,wlen); //not null terminated
    newStr[wlen] = '\0';

    printf("\n--%s--",newStr);

    //PASS POINTER TO POINTER for malloc to work / malloc inside another function
    *ptr = malloc(sizeof(newStr)+1); //memory


    strcat(*ptr,newStr);    
    printf("\nPTR is : %s",*ptr);


    printf("\n- leaving trimspaces function -");

}


int main(){
    addRecord("   ertsfs  ","  120,Dans st  ","   111 000 222");

}

No need to pass ptr as argument to trimspaces calls.

This works (even if string is just whitespaces or empty):

char *trimspaces(char *string){
    size_t len = strlen(string);
    char *s = string; //start
    char *e = string + len - 1; //end

    while(s <= e && isspace(*s)) s++;
    while(e >= s && isspace(*e)) e--;

    size_t size = e - s + 1;
    char *ptr = (char*) malloc(size + 1);

    int i;
    for(i = 0; i < size; i++)
        ptr[i] = s[i];
    ptr[i] = '\0';

    return ptr;
}

If you encounter any problem with pointers out-of-bound (which I doubt) try this using indexes instead of pointers:

char *trimspaces(char *string){
    int len = strlen(string);
    int s = 0; //start
    int e = len - 1; //end

    while(s <= e && isspace(string[s])) s++;
    while(e >= s && isspace(string[e])) e--;

    int size = e - s + 1;
    char *ptr = (char *) malloc(size + 1);

    int i;
    for(i = 0; i < size; i++)
        ptr[i] = string[i + s];
    ptr[i] = '\0';

    return ptr;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM