3
\$\begingroup\$

Updated previously posted string struct and utility functions

Previous link: User-friendly string struct and utility functions

What is updated ?

  • typedef of sstring is a major update. previously, users had to do sstring var; and then var._str = value, But now, users can do sstring var = "Value";
  • Buffer overflows have been fixed
  • major bugs and features have been improved and fixed
  • All functions now have error checking methods
  • conversion from c-style array strings to sstrings and vice-versa is now easily possible through sstr2cstr() and cstr2sstr() functions!
  • conversion from string to number [double/float/int] type is easily possible. It has some unique things such as it can tell if the string is a number, if an error has occured and returns the actual number!
  • Sstrinputpass() introduces new type of password input method!
  • All functions have slight improvements

Any suggestions, bug-report or feedbacks are Happily Welcomed!

- Files -

sstring.h

#ifndef SSTRING_H_DEFINED
//stdbool for sstrnum typedef
#include<stdbool.h>
#define SSTRING_H_DEFINED
//define the maximum char limit here
#define GLOBAL_MAX_CHAR_LIMIT 400

#define NO_ERR -1
#define GMCL_CORRUPT -10
#define INVALID_ARGS -11
#define GMCL_ERR -12

typedef struct{
    double _num;
    bool is_num;
    int _err;
}sstrnum;

typedef char * sstring;

typedef struct{
    char _str[GLOBAL_MAX_CHAR_LIMIT];
    int _err;
}sstrfunc;

typedef struct{
    char _char;
    int _err;
}charfunc;

typedef sstrfunc sstrfuncerr;

void nullify(char * _Buff,int _count);
sstrnum sstr2num(sstring _str);
sstrfunc cstr2sstr(char * _Buff);
int sstr2cstr(sstring _sstr,char * _Cstr,size_t _upto);
sstrfunc sstrappend(sstring _var1,sstring _var2);
sstrfunc sstrinput();
ssize_t sstrfind(size_t init,sstring _str,sstring _find);
size_t sstrlen(sstring _str);
sstrfunc ssetchar(sstring _str,ssize_t _pos,char _ch);
sstrfunc ssubstr(sstring _str,int _pos,size_t _len);
charfunc sgetchar(sstring _str,ssize_t _pos);
sstrfunc sstrinputpass(sstring show);
void showerrs();

#endif

sstring.c

#include<stdio.h>
#include<string.h>
#include "sstring.h"
#include<stdbool.h>
#include<conio.h>
#include<stdlib.h>
#include<math.h>

/*
A Big Note To the ones saying dont return Local Variable Adresses

Below functions dont return any local variable addresses
to prove it, call the functions MULTIPLE times  -> you will see yourself

They return a typedef of strfunc which contains the string in array format
when the user does [functionname]([parameters])._str; the str array value is sent to the pointer
so no issue will be created! :D

*/


size_t sstrlen(sstring _str){
    //just as support for sstrings
    // all functions included are better!
    return strlen(_str);
}

bool isGMCLCorrupt(){
    //checks if global max char limit is corrupted
    if(GLOBAL_MAX_CHAR_LIMIT<=0){
        return true;
    }else{
        return false;
    }
}

sstrfunc cstr2sstr(char * _Buff){
    sstrfunc _null;
    nullify(_null._str,GLOBAL_MAX_CHAR_LIMIT);
    _null._err = NO_ERR;
    if(isGMCLCorrupt()){
        _null._err = GMCL_CORRUPT;
        return _null;
    }
    if(strlen(_Buff)>=GLOBAL_MAX_CHAR_LIMIT){
        _null._err = GMCL_ERR;
        return _null;
    }
    //blank string
    if(strlen(_Buff)==0){
        return _null;
    }
    sstrfunc _ret;
    strncpy(_ret._str,_Buff,strlen(_Buff));
    _ret._err = NO_ERR;
    return _ret;
}

int sstr2cstr(sstring _sstr,char * _Cstr,size_t _upto){
    
    //first null out the _Cstr upto given length
    nullify(_Cstr,_upto);
    
    if(isGMCLCorrupt()){
        return GMCL_CORRUPT;
    }
    if(sstrlen(_sstr)>=GLOBAL_MAX_CHAR_LIMIT){
        return GMCL_ERR;
    }
    
    //blank string
    if(sstrlen(_sstr)==0){
        return NO_ERR;
    }
    
    strncpy(_Cstr,_sstr,_upto);
    return NO_ERR;
}

sstrnum sstr2num(sstring _str){
    char cchar;
    int minus = 1;
    int plus=0;
    sstrnum _return;
    int pointplace=0;
    _return._err = NO_ERR;
    _return.is_num = true;
    if(isGMCLCorrupt()){
        _return._err = GMCL_CORRUPT;
        _return._num = 0;
        _return.is_num = false;
        return _return;
    }else if(sstrlen(_str)>=GLOBAL_MAX_CHAR_LIMIT){
        _return._err = GMCL_ERR;
        _return._num = 0;
        _return.is_num = false;
        return _return;
    }
    for(int i=0;i<sstrlen(_str);i++){
        cchar = _str[i];
        //if non integer found
        if(cchar<'0'||cchar>'9'){
            if(cchar=='-'&&i==0){
                minus = -1;
            }else if(cchar=='-'&&i>0){
                _return._num = 0;
                _return.is_num = false;
                _return._err = NO_ERR;
                return _return;
            }else if(cchar=='.'&&pointplace==0){
                pointplace+=1;
            }else if(cchar=='.'&&!(pointplace==0)){
                _return._num = 0;
                _return.is_num = false;
                _return._err = NO_ERR;
                return _return;
            }else if(cchar=='+'&&plus==0){
                plus=1;
            }else if(cchar=='+'&&plus==1){
                _return._num = 0;
                _return.is_num = false;
                _return._err = NO_ERR;
                return _return;
            }else{
                _return._num = 0;
                _return.is_num = false;
                _return._err = NO_ERR;
                return _return;
            }
        }else{
            if(i==0){
                _return._num =cchar-'0';
            }else{
                if(pointplace){
                    _return._num+= (cchar-'0')/pow(10,pointplace);
                    pointplace+=1;
                }else{
                    _return._num*=10;
                    _return._num+= (cchar-'0');
                }
            }
        }
    }
    _return._num*=minus;
    return _return;
    
}

sstrfunc ssubstr(sstring _str,int _pos,size_t _len){
    //dont store anything make null return value
    sstrfunc _null;
    
    //is global max char limit corrupted??
    //returning null means error was caught!
    if(isGMCLCorrupt()){
        //gmcl is corrupt! errcode: #defined in sstring.h
        _null._err = GMCL_CORRUPT;
        return _null;
    }
    if(_pos<0){
        _null._err = INVALID_ARGS;
        return _null;
    }
    if(sstrlen(_str)>=GLOBAL_MAX_CHAR_LIMIT||_pos>=GLOBAL_MAX_CHAR_LIMIT||_len>=GLOBAL_MAX_CHAR_LIMIT){
        _null._err = GMCL_ERR;
        return _null;
    }
    
    if(_pos>=sstrlen(_str)||_pos<0||_len>=sstrlen(_str)||_len<0){
        _null._err = INVALID_ARGS;
        return _null;
    }
    
    sstrfunc _ret;
    
    _ret._err = NO_ERR;
    strncpy(_ret._str,_str+_pos,_len);
    _ret._str[_len] = '\0';
    return _ret;
    
}

sstrfunc sstrappend(sstring _var1,sstring _var2){
    //dont store anything make null return value
    sstrfunc _null;
    
    //is global max char limit corrupted??
    //returning null means error was caught!
    if(isGMCLCorrupt()){
        //gmcl is corrupt! errcode: #defined in sstring.h
        _null._err = GMCL_CORRUPT;
        return _null;
    }
    
    
    if(sstrlen(_var1)+sstrlen(_var2)>=GLOBAL_MAX_CHAR_LIMIT){
        _null._err = GMCL_ERR;
        return _null;
    }
    //use of string.h functions -> far easier than my previous headscratching!
    char _ret1[sstrlen(_var1)+sstrlen(_var2)];
    strcpy(_ret1,_var1);
    strcat(_ret1,_var2);
    sstrfunc _ret;
    //no errors :D
    _ret._err = NO_ERR;
    strcpy(_ret._str,_ret1);
    return _ret;
}

void nullify(char * _Buff,int _count){
    if(isGMCLCorrupt()){
        exit(GMCL_CORRUPT);
    }else if(_count>GLOBAL_MAX_CHAR_LIMIT+1){
        exit(GMCL_ERR);
    }else{
        for(int i=0;i<_count+1;i++){
            _Buff[i] = '\0';
        }
    }
}

sstrfunc sstrinput(){
    //dont store anything make null return value
    sstrfunc _null;
    //is global max char limit corrupted??
    //returning null means error was caught!
    if(isGMCLCorrupt()){
        _null._err = GMCL_CORRUPT;
        return _null;
    }
    char _tmp[GLOBAL_MAX_CHAR_LIMIT];
    //fgets for safety :)
    fgets(_tmp,GLOBAL_MAX_CHAR_LIMIT,stdin);
    sstrfunc _ret;
    //ret._str is array upto GLOBAL_MAX_CHAR_LIMIT
    //also tmp is array upto GLOBAL_MAX_CHAR_LIMIT
    //so its safe :) to use strcpy same as strncpy
    strcpy(_ret._str,_tmp);
    //'\n' avoided
    _ret._str[strlen(_tmp)-1] = '\0';
    _ret._err = NO_ERR;
    return _ret;
}

sstrfunc sstrinputpass(sstring show){
    //dont store anything make null return value
    sstrfunc _null;
    //is global max char limit corrupted??
    //returning null means error was caught!
    if(isGMCLCorrupt()){
        _null._err = GMCL_CORRUPT;
        return _null;
    }
    char _tmp[GLOBAL_MAX_CHAR_LIMIT];
    //nullify string [if i dont use this WiErD things happen]
    nullify(_tmp,GLOBAL_MAX_CHAR_LIMIT+1);
    char tmpchar;
    int done=0;
    //until a certain char has not been pressed
    while(1>0){
        //take chars only upto global max char limit
        if(done>=GLOBAL_MAX_CHAR_LIMIT-1){
            break;
        }
        tmpchar = getch();
        if(tmpchar=='\r'){
            break;
        }else if(tmpchar=='\b'){
            if(strlen(_tmp)>0){
                _tmp[strlen(_tmp)-1] = '\0';
                for(int i=0;i<sstrlen(show);i++){
                    printf("\b");
                }
                for(int i=0;i<sstrlen(show);i++){
                    printf(" ");
                }
                for(int i=0;i<sstrlen(show);i++){
                    printf("\b");
                }
            }
        }else{
            _tmp[strlen(_tmp)]=tmpchar;
            printf(show);
        
        done+=1;}
    }
    //print newline buffer
    printf("\n");
    
    sstrfunc _ret;
    //ret._str is array upto GLOBAL_MAX_CHAR_LIMIT
    //also tmp is array upto GLOBAL_MAX_CHAR_LIMIT
    //so its safe :) to use strcpy same as strncpy
    strcpy(_ret._str,_tmp);
    //no errors
    _ret._err = NO_ERR;
    return _ret;
}

sstrfunc ssetchar(sstring _str,ssize_t _pos,char _ch){
    sstrfunc _null;
    //is global max char limit corrupted??
    //returning null means error was caught!
    if(isGMCLCorrupt()){
        _null._err = GMCL_CORRUPT;
        return _null;
    }

    sstrfunc _ret;
    if(sstrlen(_str)>=GLOBAL_MAX_CHAR_LIMIT){
        _null._err = GMCL_ERR;
        return _null;
    }
    if(_pos>=sstrlen(_str)||_pos<0){
        _null._err = INVALID_ARGS;
        return _null;
    }
    strcpy(_ret._str,_str);
    _ret._str[_pos] = _ch;
    _ret._err = NO_ERR;

    return _ret;
}

void showerrs(){
    printf("\n---- ERRORS Corresponding to their codes ----\n");
    printf("%d :- GMCL [global max char limit] is corrupted\n",GMCL_CORRUPT);
    printf("%d :- INVALID ARGS [the provided arguments are invalid]\n",INVALID_ARGS);
    printf("%d :- GMCL_ERR [provided variable has length greater than GMCL]\n",GMCL_ERR);
    printf("Other :- Unknown Error - Not Known Errors \n");
    printf("---------------------------------------------\n");
}


charfunc sgetchar(sstring _str,ssize_t _pos){
    charfunc _null;
    //is global max char limit corrupted??
    if(isGMCLCorrupt()){
        _null._err = GMCL_CORRUPT;
        return _null;
    }
    // condition checking which are likely make error after
    if(sstrlen(_str)>=GLOBAL_MAX_CHAR_LIMIT){
        _null._err = GMCL_ERR;
        return _null;
    }
    
    if(_pos>=sstrlen(_str)||_pos<0||sstrlen(_str)<0){
        _null._err = INVALID_ARGS;
        return _null;
    }   
    charfunc chr;
    chr._char = _str[_pos];
    chr._err = NO_ERR;
    return chr;
}

//if the length of string is in size_t
//and charachters in it can also be beyond int who knows!
//used ssize_t to support returning negative numbers, i.e -> -1 and errors

//init is the place to start finding
ssize_t sstrfind(size_t init,sstring _str,sstring _find){
    size_t _len1 = sstrlen(_str);
    size_t _len2 = sstrlen(_find);
    size_t matching = 0;
    
    //is global max char limit corrupted??
    if(isGMCLCorrupt()){
        return GMCL_CORRUPT;
    }
    
    if(sstrlen(_str)>=GLOBAL_MAX_CHAR_LIMIT||sstrlen(_find)>=GLOBAL_MAX_CHAR_LIMIT){
        return GMCL_ERR;
    }
    
    //some weird conditions check [user, are u fooling the function ?]
    if(_len2>_len1||init<0||init>_len1-1){
        return INVALID_ARGS;
    }
    
    //security check
    if(_len1>=GLOBAL_MAX_CHAR_LIMIT||_len2>=GLOBAL_MAX_CHAR_LIMIT){
        return GMCL_ERR;
    }
    
    if(_len1==0||_len2==0){
        //obviously it wont be found if the string itself is null or the tobefound string is null
        return -1;
    }
    
    //the main finder -by myself
    for(size_t i=init;i<_len1+1;i++){
        if(_str[i]==_find[0]){
            for(int z=0;z<_len2+1;z++){
                if(matching==_len2){
                    return i;
                }
                else if(_str[i+z]==_find[z]){
                    matching+=1;
                }
                else{
                    matching=0;
                    break;
                }
            }
        }
    }
    return -1;
}

example-usage.c

#include<stdio.h>
#include "sstring.h"
#include<string.h>
#include<stdbool.h>
#include<stdlib.h>

/*
Example usage of sstring.h functions
initially we dont need to include stdlib.h or string.h
But are included for c-style arr conversion showcase & for exit() functions inside here
*/

//User can handle errors in their **Own** Way

void ErrCheck(sstrfuncerr _str){
    if(_str._err!=NO_ERR){
        printf("\n--- Error %d ---",_str._err);
        showerrs();
        //terminate the program upon error
        //again user can do anything like return value and etc.
        exit(_str._err);
    }   
}

void ErrCodeCheck(int _code){
    if(_code<NO_ERR){
        printf("\n--- Error %d ---",_code);
        showerrs();
        //terminate the program upon error
        //again user can do anything like return value and etc.
        exit(_code);
    }
}

void GenerateErr(int _code){
    if(_code!=NO_ERR){
        printf("\n--- Error %d ---",_code);
        showerrs();
        exit(_code);
    }
}

int main(){
    //---------------- Simplicity Showcase -------------------
    
    sstring a;
    a = "This is a sample string!";
    printf("Sample: %s \n\n",a);
    
    // ----------------- Functions ShowCase -------------------
    
    //all functions of sstring have error checking methods!
    //create an error checking variable
    sstrfuncerr var;
    
    
    // -=-=- Sstrinput() -=-=-
    // No other scanf() or gets() support sstring so, specially sstrinput() for sstrings!
    printf("Sstrinput: ");
    var = sstrinput();
    
    //errcheck
    ErrCheck(var);
    a = var._str;
    
    //-=-=- Sstrlen() -=-=-
    // strlen() from string.h also can do this but added as a support for sstrings!
    printf("Length of a: %d\n\n",sstrlen(a)); // Or printf("Length of a: %d\n\n",strlen(a)); <- from string.h same thing!
    
    //-=-=- Sstrfind() -=-=-
    //lets find space
    int check;
    check = sstrfind(0,a," ");
    
    //errcheck
    //default err check
    ErrCodeCheck(check);
    //unknown err check
    if(check>sstrlen(a)&&check!=-1){
        GenerateErr(check);
    }
    
    if(check==-1){
        printf("Space not found!\n");
    }else{
        printf("Space found at %d charachter!\n",check);
    }
    
    
    
    //-=-=- Ssubstr() -=-=-
    var = ssubstr(a,0,sstrlen(a)-2);
    
    //errcheck
    ErrCheck(var);
    a = var._str;
    
    printf("Without having last two chars : %s\n",a);
    
    //Inputting passwords so easy!
    printf("\nEnter Password: ");
    var = sstrinputpass("*");
    
    //errcheck
    ErrCheck(var);
    
    a = var._str;
    printf("Shh! Your password is : \"%s\"\n",a); 
    
    //Converting to number
    printf("\nEnter a num: ");
    var = sstrinput();
    
    //errcheck
    ErrCheck(var);
    a = var._str;
    
    double num;
    sstrnum ret_num;
    
    //main conversion works on float, double or int values all negative or positive or '+' in front!
    //also can tell if the given string is number or not
    //also has error checking support!
    ret_num = sstr2num(a);
    
    //error check
    if(ret_num._err!=NO_ERR){
        
        GenerateErr(ret_num._err);

    //if not a number
    }else if(ret_num.is_num==false){
        
        printf("You didnt enter a number!");

    //if a number
    }else if(ret_num.is_num==true){
        num = ret_num._num;
        printf("You entered: %f\n",num);
    }
    
    //-=-=- Conversion from array type to sstring and vice-versa -=-=-
    
    char arr_type_str[GLOBAL_MAX_CHAR_LIMIT];
    sstring sstr_type_str;
    int _errcheck;
    
    //first sstring to arr type strings
    
    //fill up sstring
    sstr_type_str = "If you see this, Sstr2Arr conversion success done!";
    //convert
    _errcheck = sstr2cstr(sstr_type_str,arr_type_str,GLOBAL_MAX_CHAR_LIMIT);
    //error check
    ErrCodeCheck(_errcheck);
    //display
    printf("\nSstr 2 Arr: %s\n",arr_type_str);
    
    //Now arr type strings to sstrings!
    
    //first lets nullify our string [previously used]
    nullify(arr_type_str,sstrlen(arr_type_str));
    //fill up array type string
    strcpy(arr_type_str,"If you see this, Arr2Sstr conversion success done!");
    //errcheck first
    ErrCheck(cstr2sstr(arr_type_str));
    //convert
    sstr_type_str = cstr2sstr(arr_type_str)._str;
    //display
    printf("Arr 2 Sstr: %s\n",sstr_type_str);   
}
\$\endgroup\$
2
  • \$\begingroup\$ Why _ begins so many struct member names? \$\endgroup\$ Nov 4, 2021 at 14:18
  • \$\begingroup\$ @chux its meant to be internal so _ is used \$\endgroup\$
    – Pear
    Nov 6, 2021 at 4:37

2 Answers 2

4
\$\begingroup\$

conversion from c-style array strings to sstrings and vice-versa is now easily possible through sstr2cstr() and cstr2sstr() functions!

Yes possible, but inefficient.

cstr2sstr() performs O(GLOBAL_MAX_CHAR_LIMIT) operations even when the C string is much shorter. This occurs in return _ret;

Within cstr2sstr() is the curious strncpy(_ret._str,_Buff,strlen(_Buff)); rather than with simple memcpy(_ret._str, _Buff, strlen(_Buff)); of which code could also use the prior strlen(_Buff) and save that result to avoid another expensive strlen() call. A good compile may do that for you.

Bug 1

Consider nullify() zeros GLOBAL_MAX_CHAR_LIMIT+2 elements of _tmp[] - off by 2!

char _tmp[GLOBAL_MAX_CHAR_LIMIT];
nullify(_tmp,GLOBAL_MAX_CHAR_LIMIT+1);

void nullify(char * _Buff,int _count){
  ...
    for(int i=0;i<_count+1;i++){
        _Buff[i] = '\0';
    }

Bug 2

fgets(_tmp,GLOBAL_MAX_CHAR_LIMIT,stdin); does not have the return value checked, so following code lacks knowing if _tmp is in fact a string.

Bug 3

Wrong printf specifier for size_t --> undefined behavior.

// printf("Length of a: %d\n\n",sstrlen(a));
printf("Length of a: %zu\n\n", sstrlen(a));

Also with code like for(int i=0;i<sstrlen(show);i++){, a well enabled compiler would have warned.

This, not fully using your compiler's warnings is the biggest mistake.

Underestimating FP

"conversion from string to number [double/float/int] type is easily possible ..."

I look forward to seeing that easy code. I suspect it will have unexpected weaknesses.

Compile Error Check

The isGMCLCorrupt() test deserves to be a _Static_assert() compile time test.

Missing use of const

const allows greater optimization and wider use.

// sstrfunc cstr2sstr(char * _Buff);
sstrfunc cstr2sstr(const char * _Buff);

Large arrays for C strings

sstr2cstr() obliges the destination C string to be sized GLOBAL_MAX_CHAR_LIMIT, yet a C string ends with the first null character. Very inefficient.

Namespace

The defines, types and functions of sstring.h are all over the place. Consider a common prefix to locate them lexicographically.

Documentation

sstring.h deserves documentation to high-light overall usage and function particulars. Users should not need access to sstring.c to discern general function usage.

Design

I find code passing around the large sstrfunc objects and requiring large string arrays as wholly inefficient and recommend a new design.

\$\endgroup\$
15
  • \$\begingroup\$ Bug - 1 : every function checks if the specified strings length is [greater or equal] and if true terminates the process with returning error. so doing GLOBAL_MAX_CHAR_LIMIT + 1 in the loop wouldn't cause any bugs. Bug - 2 : Even if the user presses enter without writing any charachters no bugs are found . errors occur if you try to get substr of it because its a null string. Bug - 3: Yeah i understand that but thats located in example-usage.c not in the header files or functions. so the mistake is in example file! \$\endgroup\$
    – Pear
    Nov 5, 2021 at 4:15
  • \$\begingroup\$ Underestimating fp : The function returns a typedef of strnum. the strnum contains : bool is_num , int err, double _num. As far as i know, converting from double type to float type or int type doesn't generate any issue. Compile error check : I am new to c and have this code as my own project. it would be thankful if you provided _how could i do that!. Missing use of const : Yeah but i dont think without using it would generate issue. Namespace & Design: please furthermore illustrate what are you trying to say and provide a little bit of example. :) \$\endgroup\$
    – Pear
    Nov 5, 2021 at 4:21
  • \$\begingroup\$ @Pear Let us review bug #1: _tmp is array 400. Code calls nullify(_tmp,401);. That function iterates 402 times with for(int i=0;i<402;i++){ _Buff[i] = '\0';. This overruns _tmp[]. \$\endgroup\$ Nov 5, 2021 at 13:21
  • \$\begingroup\$ @Pear Bug 2: fgets() is called yet there is no input - not even a '\n' (I am not talking about the "user presses enter without writing any characters"), but end-of-of-file. stdin is closed. In that case, _tmp[] remains indefinite and strcpy(_ret._str,_tmp); is UB. You have not seen this bug due to not testing for immediate end-of-file (nor the rare input input error). \$\endgroup\$ Nov 5, 2021 at 13:26
  • \$\begingroup\$ @Pear Did not see sstrnum sstr2num(sstring _str) earlier. There code compounds small (and some large) errors with each _return._num+= (cchar-'0')/pow(10,pointplace); and _return._num*=10; as the math result is not always exact. String to FP is in itself a very challenging coding task to do well. This code does OK, yet has precision trouble over the double range and overflow trouble near DBL_MAX, DBL_TRUE_MIN. The usual solution is to some extended precision and range. For now, use strtod() if a high quality result is needed. ` \$\endgroup\$ Nov 5, 2021 at 13:42
0
\$\begingroup\$

don't use conio.h That is a microsoft invention that is not portable

gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled.c" -o "untitled.o" 

untitled.c:36:42: error: unknown type name ‘size_t’
   36 | int sstr2cstr(sstring _sstr,char * _Cstr,size_t _upto);
      |                                          ^~~~~~
untitled.c:4:1: note: ‘size_t’ is defined in header ‘<stddef.h>’; did you forget to ‘#include <stddef.h>’?
    3 | #include<stdbool.h>
  +++ |+#include <stddef.h>
    4 | #define SSTRING_H_DEFINED
untitled.c:39:1: error: unknown type name ‘ssize_t’
   39 | ssize_t sstrfind(size_t init,sstring _str,sstring _find);
      | ^~~~~~~
untitled.c:39:18: error: unknown type name ‘size_t’
   39 | ssize_t sstrfind(size_t init,sstring _str,sstring _find);
      |                  ^~~~~~
untitled.c:39:18: note: ‘size_t’ is defined in header ‘<stddef.h>’; did you forget to ‘#include <stddef.h>’?
untitled.c:40:1: error: unknown type name ‘size_t’
   40 | size_t sstrlen(sstring _str);
      | ^~~~~~
untitled.c:40:1: note: ‘size_t’ is defined in header ‘<stddef.h>’; did you forget to ‘#include <stddef.h>’?
untitled.c:41:32: error: unknown type name ‘ssize_t’
   41 | sstrfunc ssetchar(sstring _str,ssize_t _pos,char _ch);
      |                                ^~~~~~~
untitled.c:42:40: error: unknown type name ‘size_t’
   42 | sstrfunc ssubstr(sstring _str,int _pos,size_t _len);
      |                                        ^~~~~~
untitled.c:42:40: note: ‘size_t’ is defined in header ‘<stddef.h>’; did you forget to ‘#include <stddef.h>’?
untitled.c:43:32: error: unknown type name ‘ssize_t’
   43 | charfunc sgetchar(sstring _str,ssize_t _pos);
      |                                ^~~~~~~
untitled.c:72:8: error: conflicting types for ‘sstrlen’
   72 | size_t sstrlen(sstring _str){
      |        ^~~~~~~
untitled.c:40:8: note: previous declaration of ‘sstrlen’ was here
   40 | size_t sstrlen(sstring _str);
      |        ^~~~~~~
untitled.c: In function ‘sstr2cstr’:
untitled.c:112:19: warning: conversion from ‘size_t’ {aka ‘long unsigned int’} to ‘int’ may change value [-Wconversion]
  112 |     nullify(_Cstr,_upto);
      |                   ^~~~~
untitled.c: In function ‘sstr2num’:
untitled.c:149:18: warning: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Wsign-compare]
  149 |     for(int i=0;i<sstrlen(_str);i++){
      |                  ^
untitled.c: In function ‘ssubstr’:
untitled.c:219:12: warning: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Wsign-compare]
  219 |     if(_pos>=sstrlen(_str)||_pos<0||_len>=sstrlen(_str)||_len<0){
      |            ^~
untitled.c:219:62: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
  219 |     if(_pos>=sstrlen(_str)||_pos<0||_len>=sstrlen(_str)||_len<0){
      |                                                              ^
untitled.c: In function ‘nullify’:
untitled.c:266:11: error: unknown type name ‘Compilation’
  266 |     }else{Compilation failed.
      |           ^~~~~~~~~~~
untitled.c:266:29: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
  266 |     }else{Compilation failed.
      |                             ^
untitled.c:267:21: error: ‘i’ undeclared (first use in this function)
  267 |         for(int i=0;i<_count+1;i++){
      |                     ^
untitled.c:267:21: note: each undeclared identifier is reported only once for each function it appears in
untitled.c:267:35: error: expected ‘;’ before ‘)’ token
  267 |         for(int i=0;i<_count+1;i++){
      |                                   ^
      |                                   ;
untitled.c:267:35: error: expected statement before ‘)’ token
untitled.c:261:21: warning: parameter ‘_Buff’ set but not used [-Wunused-but-set-parameter]
  261 | void nullify(char * _Buff,int _count){
      |              ~~~~~~~^~~~~
untitled.c: In function ‘sstrinputpass’:
untitled.c:316:19: warning: implicit declaration of function ‘getch’; did you mean ‘getc’? [-Wimplicit-function-declaration]
  316 |         tmpchar = getch();
      |                   ^~~~~
      |                   getc
untitled.c:316:19: warning: conversion from ‘int’ to ‘char’ may change value [-Wconversion]
untitled.c:322:30: warning: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Wsign-compare]
  322 |                 for(int i=0;i<sstrlen(show);i++){
      |                              ^
untitled.c:325:30: warning: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Wsign-compare]
  325 |                 for(int i=0;i<sstrlen(show);i++){
      |                              ^
untitled.c:328:30: warning: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Wsign-compare]
  328 |                 for(int i=0;i<sstrlen(show);i++){
      |                              ^
untitled.c:334:13: warning: format not a string literal and no format arguments [-Wformat-security]
  334 |             printf(show);
      |             ^~~~~~
untitled.c: In function ‘ssetchar’:
untitled.c:365:12: warning: comparison of integer expressions of different signedness: ‘ssize_t’ {aka ‘long int’} and ‘size_t’ {aka ‘long unsigned int’} [-Wsign-compare]
  365 |     if(_pos>=sstrlen(_str)||_pos<0){
      |            ^~
untitled.c: In function ‘sgetchar’:
untitled.c:399:12: warning: comparison of integer expressions of different signedness: ‘ssize_t’ {aka ‘long int’} and ‘size_t’ {aka ‘long unsigned int’} [-Wsign-compare]
  399 |     if(_pos>=sstrlen(_str)||_pos<0||sstrlen(_str)<0){
      |            ^~
untitled.c:399:50: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
  399 |     if(_pos>=sstrlen(_str)||_pos<0||sstrlen(_str)<0){
      |                                                  ^
untitled.c: In function ‘sstrfind’:
untitled.c:429:25: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits]
  429 |     if(_len2>_len1||init<0||init>_len1-1){
      |                         ^
untitled.c:446:26: warning: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Wsign-compare]
  446 |             for(int z=0;z<_len2+1;z++){
      |                          ^
untitled.c:448:28: warning: conversion to ‘ssize_t’ {aka ‘long int’} from ‘size_t’ {aka ‘long unsigned int’} may change the sign of the result [-Wsign-conversion]
  448 |                     return i;
      |                            ^
untitled.c:450:31: warning: conversion to ‘size_t’ {aka ‘long unsigned int’} from ‘int’ may change the sign of the result [-Wsign-conversion]
  450 |                 else if(_str[i+z]==_find[z]){
      |                               ^
untitled.c: At top level:
untitled.c:464:5: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘-’ token
  464 | gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled.c" -o "untitled.o" (in directory: /home/richard/Documents/forum)
      |     ^
Compilation failed.
\$\endgroup\$
3
  • \$\begingroup\$ i have used conio.h for getch() function. Also did u include the header file? \$\endgroup\$
    – Pear
    Nov 5, 2021 at 12:43
  • \$\begingroup\$ user3629249, "don't use conio.h That is a microsoft invention" --> Sure MS invented it? I suspect they mimicked some prior art. I do agree with the idea of avoiding non-standard functions, especially when getc() would suffice here. \$\endgroup\$ Nov 5, 2021 at 13:57
  • \$\begingroup\$ I placed your header file first, The result is posted in my answer \$\endgroup\$ Nov 6, 2021 at 23:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.