Converting a string into 2d array in c - arrays

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;
}

Related

C - fit string on a fixed width

I would like to fit a string into multiple rows of a fixed width. I managed to separate the string into different rows so that their length will not pass the fixed width, but the problem is that some rows are not width (80) characters long, this is why I am trying to distribute the extra_space by adding spaces between words.
#include <stdio.h>
#include <string.h>
#include "stringdefault.h"
#include <conio.h>
#include <stdlib.h>
int main(){
int width = 80;
char s1[10000];
char substring[100] = " ";
char space = ' ';
gets(s1);
removeSpaces(s1);
char *base,*right_margin;
int extraSpace, numWords, numSpaces, incrementEachSpaceby, ind1, ind2, k;
int length;
length = string_length(s1);
base = s1;
for(int i = 0; i < width; i++)
{
printf("%d", i%10);
}
printf("\n");
while(*base)
{
if(length <= width)
{
puts(base); // display string
return(0); //and leave
}
right_margin = base+width;
while(!isspace(*right_margin))
{
right_margin--;
if( right_margin == base)
{
right_margin += width;
while(!isspace(*right_margin))
{
if( *right_margin == '\0')
break;
right_margin++;
}
}
}
*right_margin = '\0';
if(string_length(base) < width)
{
char *newStr = malloc(width);
extraSpace = width - string_length(base);
numWords = numberOfWords(base);
numSpaces = numWords - 1;
incrementEachSpaceby = extraSpace/numSpaces;
ind1 = 0;
ind2 = 0;
while (ind2 < width)
{
newStr[ind2] = base[ind1];
ind1++;
ind2++;
}
for(int i = 0; newStr[i]!='\0'; i++)
if((isspace(newStr[i])))
{
if(extraSpace > 0)
k = extraSpace;
else
k = 1;
while(k)
{
insert_substring(newStr, substring, i);
k--;
}
}
puts(newStr);
}
else
puts(base);
length -= right_margin-base+1; // +1 for the space
base = right_margin+1;
}
return 0;
}
stringdefault.h
int string_length(char s[])
{
int length = 0;
for(int i=0; s[i]!='\0'; i++)
length++;
return length;
}
char *substring(char *string, int position, int length)
{
char *pointer;
int c;
pointer = malloc(length+1);
if( pointer == NULL )
exit(EXIT_FAILURE);
for( c = 0 ; c < length ; c++ )
*(pointer+c) = *((string+position-1)+c);
*(pointer+c) = '\0';
return pointer;
}
void insert_substring(char *a, char *b, int position)
{
char *f, *e;
int length;
length = strlen(a);
f = substring(a, 1, position - 1 );
e = substring(a, position, length-position+1);
strcpy(a, "");
strcat(a, f);
free(f);
strcat(a, b);
strcat(a, e);
free(e);
}
char *removeSpaces(char *str)
{
int ip_ind = 0;
char *ptr;
while(*(str + ip_ind))
{
if ( (*(str + ip_ind) == *(str + ip_ind + 1)) && (*(str + ip_ind)==' ') )
{
ptr = str + ip_ind+1;
do{
*(ptr-1) = *ptr;
}while(*ptr++ != '\0');
}
else
ip_ind++;
}
*(str + ip_ind) = '\0';
return str;
}
The output that I get without the while loop inside the if statement
It seems that the newStr set of characters, contains spaces before it's first character.

Creating an array of strings - c

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void main()
{
char str[1000], *arr;
int i = 0,len,counter=0,j=0;
arr = (char*)malloc((sizeof(char*) * 1000));
for (i = 0; str[i] != '\0'; i++)
{
str[i] = getchar();
if (str[i] == ' ')
{
str[i] = '\0';
arr[j] = malloc(sizeof(char)*counter);
strcpy_s(&arr[j], counter * sizeof(char), &str[i - counter]);//i dont know why but this line does me some problems
j++;
counter = 0;
}
counter++;
}
}
I am trying to create an array of strings but the strcpy is not letting me and i do not know why. help will be much appreciated.
This error is because str[i - counter] is a char, not a pointer. You need to write &str[i - counter] or (str + i - counter).
See the signature of strcpy_s: errno_t strcpy_s(char *restrict dest, rsize_t destsz, const char *restrict src);
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int count_spaces(char *str)
{
int count = 0;
if (str == NULL || strlen(str) == 0)
return (0);
int i = 0;
while (str[i])
{
if (str[i] == ' ')
count++;
i++;
}
return count++;
}
char **get_strings(char *str)
{
if (str == NULL || strlen(str) == 0)
return NULL;
char **dest;
if ((dest = malloc(sizeof(char*) * (count_spaces(str) + 1))) == NULL || (dest[0] = malloc(sizeof(char) * (strlen(str) + 1))) == NULL)
return NULL;
int i = 0, j = 0, k = 0;
while (str[i])
{
if (str[i] == ' ')
{
dest[k][j] = '\0';
j = 0;
dest[++k] = malloc(sizeof(char) * (strlen(str) + 1));
}
else
dest[k][j++] = str[i];
i++;
}
dest[k + 1] = NULL;
return dest;
}
int main()
{
char **dest;
dest = get_strings("this is a test for stackoverflow");
int i = 0;
while (dest[i] != NULL)
printf("%s\n", dest[i++]);
}
here is a quick (non-perfect) example to do it with char **
you give a string as parameter and the function will store each segment using space as delimiter in a char **
you can print it as i did in the main. Don't forget to free when you're done

Inserting a value into an array and arranging array according to value c

char num = '5';
strcpy(array, "2,3,7,9")
Hi guys, any ideas if want to insert 5 into the array according to the value which will result in, how would i go about doing this?
array = "2,3,5,7,9"
#include <stdio.h>
#include <string.h>
void insert_string(char *target, const char *to_insert, int index) {
int count = 0;
int i;
int move_dst;
int insert_comma = 0;
int to_len = strlen(to_insert);
if (index < 0) index = 0;
if (index <= 0) {
i = 0;
} else {
for (i = 0; target[i] != '\0'; i++) {
if (target[i] == ',') {
count++;
if (count >= index) {
i++;
break;
}
}
}
}
/* i is where to insert the string */
if (target[i] == '\0') {
/* the insertion target was end of the string */
target[i] = ',';
target[++i] = '\0';
}
move_dst = i + to_len;
if (target[i] != '\0') {
/* the sequence continues after insertion point */
move_dst++;
insert_comma = 1;
}
memmove(&target[move_dst], &target[i], strlen(&target[i]) + 1); /* copy includes termination '\0' */
memcpy(&target[i], to_insert, to_len);
if (insert_comma) target[i + to_len] = ',';
}
int main(void) {
char array[1024];
char num = '5';
char num_string[2] = {num, '\0'};
int c = 2;
strcpy(array, "2,3,7,9");
puts(array);
insert_string(array, num_string, c);
puts(array);
return 0;
}

When the string is number C language

I want to return nothing when the string is number
here is my code,
#include <string.h>
#include <ctype.h>
int num = 0;
char* findWord(char* subString) {
char* word = malloc(sizeof(char) * (strlen(subString) + 1));
int i = 0;
int Position = 0;
num = 0;
while (ispunct(subString[i]) != 0 || isspace(subString[i]) != 0) {
i++;
}
num = i;
while (ispunct(subString[i]) == 0 && isspace(subString[i]) == 0) {
word[Position] = subString[i];
i++;
Position++;
}
word[Position] = '\0';
return word;
}
char** wordList(const char* s) {
int len = strlen(s);
int i = 0;
char* Copyword = malloc(sizeof(char) * len);
strncpy(Copyword, s, len);
char** result = (char**) malloc(sizeof(char*) * (len + 1));
char* word = NULL;
word = findWord(Copyword);
char* wordEnd = Copyword;
while (*word != 0) {
result[i] = word;
wordEnd = wordEnd + strlen(word) + num;
word = findWord(wordEnd);
i++;
}
result[i] = '\0';
free(Copyword);
return result;
}
int main(void) {
char** words = wordList("1 23 456 789");
int i = 0;
while (words[i] != NULL) {
printf("%s\n", words[i]);
free(words[i]); // We're done with that word
i++;
}
free(words); // We're done with the list
return 0;
}
my code is ok when the string is sentence.
however, in this case, I want to print nothing(just like a space) when the string is number.
but what I go is
1
23
456
789
I expect to get
nothing shows here! just a space
For starters: You pass a non 0-terminated C-"string" (Copyword) to findWord() and in there call strlen() on it. This just doesn't crash your app by bad luck.

Big number adding function crashes program

I wrote an adding function for very large numbers and when it gets called, the program crashes. I am assuming that it has to do with the carrying. Here is the code:
char * bigadd(char a[], char b[]){
int i, temp;
char useadd[MAX];
char usea = strrev(a);
char useb = strrev(b);
char ret[strlen(useadd)];
char *pa, *pb, *padd;
padd = &useadd;
pa = &usea;
pb = &useb;
while(*pa != '\0' && *pb != '\0'){
if(atoi(*pa) + atoi(*pb) + temp > 9){
if(temp + atoi(*pa) + atoi(*pb) < 20){
temp = 1;
*padd = atoi(*pa) + atoi(*pb) - 10;
}
else{
temp = 2;
*padd = atoi(*pa) + atoi(*pb) - 20;
}
}
else{
*padd = atoi(*pa) + atoi(*pb);
temp = 0;
}
++padd;
++pa;
++pb;
}
i = 0;
while(useadd[i] != '\0'){
ret[i] = useadd[i];
++i;
}
return strrev(ret);
}
Thanks for all of the help. I'm sorry if this ends up being a stupid mistake.
Your program has so many problems!
char * bigadd(char a[], char b[]){
int i, temp;
char useadd[MAX]; // MAX might not be large enough
char usea = strrev(a); // should not modify argument a
// strrev() is not standard C undefined on my system
// if defined, it returns char*, not char
char useb = strrev(b); // see above
char ret[strlen(useadd)]; // useadd is uninitialized -> undefined behaviour
char *pa, *pb, *padd;
padd = &useadd; // & is incorrect, useadd is an array
pa = &usea; // same as above
pb = &useb; // idem
// forgot to initialize temp to 0
while(*pa != '\0' && *pb != '\0'){
if(atoi(*pa) + atoi(*pb) + temp > 9){ // atoi converts a string, not a char
if(temp + atoi(*pa) + atoi(*pb) < 20){ // same... sum cannot exceed 19
temp = 1;
*padd = atoi(*pa) + atoi(*pb) - 10; // atoi...
}
else{ // never reached
temp = 2;
*padd = atoi(*pa) + atoi(*pb) - 20; // atoi...
}
}
else{
*padd = atoi(*pa) + atoi(*pb); // same atoi problem
temp = 0;
}
++padd;
++pa;
++pb;
}
// if a and b have a different size, loop fails to copy digits and propagate carry
// if temp is not 0, you forget to add the leading '1'
// trailing '\0' is not set
i = 0;
while(useadd[i] != '\0'){ // undefined behaviour, '\0' not set.
ret[i] = useadd[i];
++i;
}
// forgot to set the final '\0'
// why not use strcpy?
return strrev(ret); // strrev not defined.
// if defined, returning ret, address of local array
}
Here is a complete rewrite:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *bigadd(const char a[], const char b[]) {
int ia = strlen(a);
int ib = strlen(b);
int size = 2 + (ia > ib ? ia : ib), ic = size - 1, temp = 0;
char *res = malloc(size);
if (res) {
res[--ic] = '\0';
while (ia + ib) {
if (ia > 0) temp += a[--ia] - '0';
if (ib > 0) temp += b[--ib] - '0';
res[--ic] = '0' + temp % 10;
temp /= 10;
}
if (temp) {
memmove(res + 1, res, size - 1);
*res = '1';
}
}
return res;
}
int main(int argc, char *argv[]) {
for (int i = 1; i + 1 < argc; i += 2) {
char *res = bigadd(argv[i], argv[i+1]);
printf("%s + %s = %s\n", argv[i], argv[i+1], res);
free(res);
}
}

Resources