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);
}
2 Answers 2
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.
-
\$\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– Pear2021年11月05日 04:15:43 +00:00Commented 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– Pear2021年11月05日 04:21:11 +00:00Commented Nov 5, 2021 at 4:21
-
\$\begingroup\$ @Pear Let us review bug #1:
_tmp
is array 400. Code callsnullify(_tmp,401);
. That function iterates 402 times withfor(int i=0;i<402;i++){ _Buff[i] = '0円';
. This overruns_tmp[]
. \$\endgroup\$chux– chux2021年11月05日 13:21:03 +00:00Commented 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 andstrcpy(_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\$chux– chux2021年11月05日 13:26:45 +00:00Commented 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 thedouble
range and overflow trouble nearDBL_MAX, DBL_TRUE_MIN
. The usual solution is to some extended precision and range. For now, usestrtod()
if a high quality result is needed. ` \$\endgroup\$chux– chux2021年11月05日 13:42:09 +00:00Commented Nov 5, 2021 at 13:42
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.
-
\$\begingroup\$ i have used conio.h for getch() function. Also did u include the header file? \$\endgroup\$Pear– Pear2021年11月05日 12:43:41 +00:00Commented 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\$chux– chux2021年11月05日 13:57:49 +00:00Commented Nov 5, 2021 at 13:57 -
\$\begingroup\$ I placed your header file first, The result is posted in my answer \$\endgroup\$user3629249– user36292492021年11月06日 23:22:14 +00:00Commented Nov 6, 2021 at 23:22
_
begins so manystruct
member names? \$\endgroup\$_
is used \$\endgroup\$