Custom strtok function not working as expected - c

I was trying to write my own strtok function.
char * toke(char * out, char * in, char * destr) {
int place = 0;
for(int i = 0; in[i] != '\0'; i++){
for(int d = 0; destr[d] != '\0'; d++){
if(in[i] == destr[d]){
printf("\nMatch.");
place = i;
i = 0;
while(i < place){
out[i] = in[i];
i++;
}
out[place + 1] = '\0';
i = place;
}
}
}
return out;
}
Program:
int main(){
char * pr;
char * o;
char * in = "Hello-World";
pr = toke(o, in, "-");
printf(pr);
return 0;
}
It keeps on seg-faulting and I can't figure out why.

Your 'out' pointer is not initialized and this:
out[i] = in[i];
throws the exception

Related

Each function works, but not together

i have string like "1111 1010 101010" and i have two functions
int getFirstNumber(char *a){
char *p = strtok(a," ");
char str[strlen(p)];
for (int i = 0; i < strlen(p); ++i){
str[i] = p[i];
}
return getBin(str);
}
int getThirdNumber(char *a){
char *p = strtok(a," ");
int k = 0;
while (p != NULL){
p = strtok(NULL," ");
if (k == 1){
break;
}
k +=1;
}
char str[strlen(p)-1];
for (int i = 0; i < strlen(p) - 1; ++i){
str[i] = p[i];
}
return getBin(str);
}
getBin
int getBin(char *a){
int k = 1;
int res;
for (int i = strlen(a) - 1; i >= 0;i -=1){
if (a[i] == '1'){
res += k;
}
k *= 2;
}
return res;
}
The problem is if i use getFirstNumber or use getThirdNumber alone, it works, but together i have Segmentation Fault. What is wrong,

Converting a string into 2d array in c

hi i have been trying to convert a string map to an 2d array but the more i change the more i get confused. now it does not compile and complains its = NUL (edited i added malloc and seems that and gives segmentation fault).
#include <unistd.h>
#include <stdlib.h>
char **stoa(char *str)
{
int i;
int j;
int k;
char **map;
//int len = ft_strlen_line(str);
//int row = ft_strlen(str);
i = 0;
j = 0;
k = 0;
//arow = row/len;
//map = malloc(j * k sizeof(char*));
map = malloc(j * sizeof(k));
while(str[i])
{
if (str[i] == '\n')
{
k = 0;
j++;
}
map[j][k] = str[i];
k++;
i++;
}
free(map);
return (map);
if (!(map = malloc(j * k * sizeof(char))))
return NULL;
}
int main(void)
{
char row12[] = "ABABABABAB\nABABABABAB\nABABABABAB\n\0";
char **map;
map = stoa(row12);
return (0);
}
Not tested.
char **stoa(char *str)
size_t nlines = 0;
size_t pos = 0;
char **array = NULL;
char **tmp;
while(*str)
{
while(*str && str[pos++] != '\n');
nlines++;
tmp = realloc(array, (nlines + 1) * sizeof(*array));
if(tmp) array = tmp;
else break;
array[nlines] = NULL;
if(array[nlines - 1] = malloc(pos + 2));
if(array[nlines - 1])
{
memcpy(array[nlines - 1], str, pos);
array[nlines - 1][pos] = 0;
str = str + pos;
if(str == '\n') str++;
pos = 0;
}
else break;
}
return array;
}

C - Copy a char into a char*

I got some troubles while I'm trying to set a char into a char* ("string")
I got lines, which is all the txt lines I fetched before, and now I'm trying to assign a char to my char*, to filter it.
Here is my actual code :
void TreatDatas(char** lignes, int sizeLignes){ // all the lines, and the size of it.
char** finalArray;
finalArray = malloc(2048 * sizeof(char*));
int sizeOfFinalArray = 0;
int i;
int j;
char* s;
char* savedCurrentString = "";
int sizeOfCurrentString = 0;
for (i = 0; i< sizeLignes; i++){
s = lignes[i];
for (j = 0; j < strlen(s); j++){ // I don't pass the first condition the first loop
if (s[j] == ',' || s[j] == '.' || s[j] == ' ' || s[j] == '\n' || s[j] == ';' || s[j] == ':'){ // Separators list
finalArray[sizeOfFinalArray] = malloc(strlen(savedCurrentString) + 1);
strcpy(finalArray[sizeOfFinalArray], savedCurrentString);
savedCurrentString = "";
sizeOfCurrentString = 0;
}else{
printf("%c , %s \n", s[j], savedCurrentString); // L - ""
printf("%d", sizeOfCurrentString); // 0
strncpy(savedCurrentString, s[j], 1); // error here
}
}
}
free(finalArray);
}
Ok I change a bit the code, now it's better, but seems to duplicate some elements. And I don't know why. Excuse me, I'm a C beginer, but I'm curious and trying to understand how that works.
void TreatDatas(char** lignes, int sizeLignes){
char** finalArray;
finalArray = malloc(2048 * sizeof(char*));
int sizeOfFinalArray = 0;
int i;
int j;
char* s;
char* savedCurrentString = "";
int sizeOfCurrentString = 0;
for (i = 0; i< sizeLignes; i++){
s = lignes[i];
printf("line : %d \n %s \n", i, s);
StringSpliter(s);
// for (j = 0; j < strlen(s); j++){
// finalArray[sizeOfFinalArray] = malloc(strlen(savedCurrentString) + 1);
// }
}
free(finalArray);
}
char * StringSpliter(char* input){
char separators[5][2] = {" ", ",", ";", ":", "."};
char ** buffer;
int bufferSize = 0;
int i;
for (i = 0; i < 5; i++){
char* token = strtok(input, separators[i]);
printf("%s", token);
while( token != NULL )
{
printf( " %s\n", token );
token = strtok(NULL, separators[i]);
}
}
printf("\n");
return "OSEF";
}
My output

Three level indirection char pointer in C causes a segment fault

I got a segment fault error at the line with the comments that contains lots of equals signs below.
The function below str_spit, I wrote it because I want to split a string using a specific char, like a comma etc.
Please help.
int str_split(char *a_str, const char delim, char *** result)
{
int word_length = 0;
int cur_cursor = 0;
int last_cursor = -1;
int e_count = 0;
*result = (char **)malloc(6 * sizeof(char *));
char *char_element_pos = a_str;
while (*char_element_pos != '\0') {
if (*char_element_pos == delim) {
char *temp_word = malloc((word_length + 1) * sizeof(char));
int i = 0;
for (i = 0; i < word_length; i++) {
temp_word[i] = a_str[last_cursor + 1 + i];
}
temp_word[word_length] = '\0';
//
*result[e_count] = temp_word;//==============this line goes wrong :(
e_count++;
last_cursor = cur_cursor;
word_length = 0;
}
else {
word_length++;
}
cur_cursor++;
char_element_pos++;
}
char *temp_word = (char *) malloc((word_length + 1) * sizeof(char));
int i = 0;
for (i = 0; i < word_length; i++) {
temp_word[i] = a_str[last_cursor + 1 + i];
}
temp_word[word_length] = '\0';
*result[e_count] = temp_word;
return e_count + 1;
}
//this is my caller function====================
int teststr_split() {
char delim = ',';
char *testStr;
testStr = (char *) "abc,cde,fgh,klj,asdfasd,3234,adfk,ad9";
char **result;
int length = str_split(testStr, delim, &result);
if (length < 0) {
printf("allocate memroy failed ,error code is:%d", length);
exit(-1);
}
free(result);
return 0;
}
I think you mean
( *result )[e_count] = temp_word;//
instead of
*result[e_count] = temp_word;//
These two expressions are equivalent only when e_count is equal to 0.:)
[] has a higher precedence than *, so probably parentheses will solve THIS problem:
(*result)[e_count] = temp_word;
I didn't check for more problems in the code. Hint: strtok() might do your job just fine.

C histogram of words printing problems

I have this code, what i want it to do is print the string that represents the word, and print the number of times it occurred in the file, instead it outprints something liek this: (a load of blank space) and then this number -1076720020, which i have no idea where it came from, how would i go about fixing this?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
struct podatki {
char beseda[1000];
int frekvenca;
};
void zamenjaj(char *str1, char *str2) {
char *beseda2 = (char *)malloc((strlen(str1) + 1) * sizeof(char));
strcpy(beseda2, str1);
strcpy(str1, str2);
strcpy(str2, beseda2);
free(beseda2);
}
int posodobi(struct podatki s[], const char unit[], int count) {
int i =0;
for (i = 0; i < count; i++) {
if (strcmp(s[i].beseda, unit) == 0) {
s[i].frekvenca++;
return count;
}
}
strcpy(s[count].beseda, unit);
s[count].frekvenca++;
return (count + 1);
}
int main() {
int stBes;
scanf("%d", &stBes);
//zacetne deklaracije
struct podatki s[1000];
char string[1000], unit[2000], c;
int i = 0;
int frekvenca = 0;
int j = 0;
int count = 0;
int num = 0;
//branje
for (i = 0; i < 1000; i++) {
s[i].frekvenca = 0;
}
i = 0;
do {
fflush(stdin);
c = getchar();
string[i++] = c;
} while (c != '\n');
//pretvori v majhne crke
char *p;
for (p = string; *p != '\0'; ++p) {
*p = tolower(*p);
}
string[i - 1] = '\0';
for (i = 0; i < strlen(string); i++) {
while (i < strlen(string) && string[i] != ' ' && !ispunct(string[i])) {
unit[j++] = string[i++];
}
if (j != 0) {
unit[j] = '\0';
count = posodobi(s, unit, count);
j = 0;
}
}
int a;
for (i = 0; i < count; ++i) {
for (j = i + 1; j < count; ++j) {
if (s[i].frekvenca < s[j].frekvenca) {
a = s[i].frekvenca;
s[i].frekvenca = s[j].frekvenca;
s[j].frekvenca = a;
zamenjaj(s[i].beseda, s[j].beseda);
}
}
}
for (i = 0; i < count; i++) {
for (j = 1; j < count; j++) {
if (s[i].frekvenca == s[j].frekvenca){
if (strcmp(s[i].beseda, s[j].beseda) < 0) {
a = s[i].frekvenca;
s[i].frekvenca = s[j].frekvenca;
s[j].frekvenca = a;
zamenjaj(s[i].beseda, s[j].beseda);
}
}
}
}
//printanje
for (i = 0; i < stBes; i++) {
printf("%s\t %d\n", s[i].beseda, s[i].beseda);
if (s[i].frekvenca > 1) {
num++;
}
}
return 0;
}
The problem is that you convert the string to lower case before nul terminating it.
Here
i = 0;
do {
fflush(stdin);
c = getchar();
string[i++] = c;
} while (c != '\n');
/* Goes here <---------------------+ */
/* | */
//pretvori v majhne crke | */
char *p; /* | */
for (p = string; *p != '\0'; ++p) {/* | */
*p = tolower(*p);/* | */
} /* | */
/* | */
string[i - 1] = '\0'; /* ---------------------+ */
You should also remove the fflush(stdin) and instead use getchar() to fetch the white space characters ignored by the previous scanf(), and please use scanf() correctly and check it's returned value.

Resources