Extracting words from a string into dynamic 2D char array - c

I have a dynamic char array that contains a string. I'm trying to extract all the words from this string into a dynamic 2d char array. Here's my code:
int rows = 1;
char *input_words = malloc((rows)*sizeof(char));
input_words = lowerCase(getInputWords(MAX_LINE_LEN, input_file)); //retrieves a string of words
char **input_words_tokenized = malloc((wordCount(input_words))*sizeof(char));
for(i = 0; i < wordCount(input_words); i++) {
input_words_tokenized[i] = malloc(MAX_KEY_LEN*sizeof(char));
}
char *t = strtok(input_words, " ");
j = 0;
while(t) {
for(i = 0; i < strlen(t); i++) {
strcpy(&input_words_tokenized[j][i], &t[i]);
printf("%c", input_words_tokenized[j][i]);
}
j++;
t = strtok(NULL, " ");
}
In my output, input_words_tokenized[j][i] only contains the first word or token from input_words. Why aren't the remaining words being tokenized and stored into input_words_tokenized[j][i]?

At least one issue.
Incorrect size calculation.
char **input_words_tokenized =
malloc((wordCount(input_words))*sizeof(char));
// wrong type ^--^
Instead of sizing to the hopefully matching type, size to the referenced type. It is easier to code right, review and maintain.
char **input_words_tokenized =
malloc((wordCount(input_words)) * sizeof *input_words_tokenized);
// ^--------------------^

Related

How to convert using atoi and strtok with multidimesional arrays?

Okay so i have this mltidim array filled with these numbers,
i wish to convert them into ints at the locations
So its gonna be a int multidim arrayint intarray[2][5][12];
Any tip on getting the converter to solve the issue? ive been on this problem a while and it
feels like im close!!
char chararray[2][5][40] =
{
{
{"307,07,33,307,11,44,307,12,31,307,16,10"},
{"308,07,52,308,11,52,308,12,35,308,16,18"},
{"309,07,24,309,11,40,309,12,30,309,16,14"},
{"310,07,15,310,11,38,310,12,36,310,16,27"},
{"311,07,12,311,11,47,311,12,30,311,16,12"}
},
{
{"314,07,12,314,11,34,314,12,27,314,16,52"},
{"315,07,15,315,11,49,315,12,31,315,16,13"},
{"316,07,59,316,11,44,316,12,38,316,16,42"},
{"317,07,52,317,11,41,317,12,30,317,16,12"},
{"318,08,03,318,11,32,318,12,39,318,16,07"}
}
};
And this is how i am trying to convert but it doesnt even let me debug just a weird error pops up..
int intarray[2][5][12];
for(int i = 0; i < 2 ; i++){
for(int j = 0; j < 5;j++){
for(int k = 0; k < 40;k++){
intarray[i][j][k] = atoi(strtok(chararray[i][j][k],","));
}
}
}
intarray[i][j][k] for i==0, j==0, k==0, represents 3 which is the the character residing at intarray[0][0][0]. This is a single char and cannot be processed using strtok().
What you really want to pass to strtok() is a complete null terminated string:
char chararray[0][0]
which is the 40 character buffer containing "307,07,33,307,11,44,307,12,31,307,16,10".
But because you probably do not want to destroy the array, you should start of by getting a duplicate of the string, something like this:
int intarray[2][5][12] = {{0}};//zero before using
int i=0;
char *dup = strdup(chararray[0][0]);//in your actual code this will be in
//a loop of `i,j` indexes, each one
//yielding the character buffers:
//{"307,07,33,307,11,44,307,12,31,307,16,10"},
//{"308,07,52,308,11,52,308,12,35,308,16,18"},
//{"309,07,24,309,11,40,309,12,30,309,16,14"},
//{"310,07,15,310,11,38,310,12,36,310,16,27"},
//{"311,07,12,311,11,47,311,12,30,311,16,12"}
//{"314,07,12,314,11,34,314,12,27,314,16,52"},
//{"315,07,15,315,11,49,315,12,31,315,16,13"},
//{"316,07,59,316,11,44,316,12,38,316,16,42"},
//{"317,07,52,317,11,41,317,12,30,317,16,12"},
//{"318,08,03,318,11,32,318,12,39,318,16,07"}
if(dup)
{
tok = strtok(dup, ",\n");
while(tok)
{
intarray[0][0][i] = atoi(tok);
tok = strtok(NULL, ",\n");
i++;
}
free(dup);//so you can use it again and again for the other sub-strings.
....
Following this approach, all of the other strings can be parsed into intarray
Each chararray[i][j] is a string - chararray[i][j][k] is a single character in that string. Unfortunately, you're passing the single character to strtok when it expects the address of the first element of the string.
When you're tokenizing repeated elements in a string, you only pass the base address once, then pass NULL for the remainder of the string. So your loop would need to be
for(int i = 0; i < 2 ; i++){
for(int j = 0; j < 5;j++){
intarray[i][j][0] = atoi( strtok( chararray[i][j], "," ) );
for(int k = 1; k < 40;k++){
intarray[i][j][k] = atoi( strtok( NULL, "," ) );
}
}
}
Note that this assumes your input is always well-formed - there's no sort of error or sanity checking.

Exception thrown at 0x7C131F4C (ucrtbased.dll) in ICP LAB ASSIGNMENT PROJECT.exe: 0xC0000005

I was trying to print some array but it won't print no matter what.
Which part did I do wrong?
Is it the array?
int main()
{
int i;
char id[3]; ///sample data wanted to print
id[0] = 'id1';
id[1] = 'id2';
id[2] = 'id3';
for (i = 1; i <= 3; ++i)
{
printf("%s", id[i]); ///The error appeared here////
}
}
i starts at 1, and goes to 3:
for (i = 1; i <= 3; ++i)
But you set up your array so that valid indicies are 0, 1, and 2.
3 is not a valid index.
Convention C-loops always look like this:
for(i = 0; i < 3; ++i)
That is, they start at 0 and go while less than the size of the array.
Not less than or equal to. That is your mistake.
Next, each element of the array is a single character.
But you are trying to initialize them with 3-letters, such as: id1.
A single character can hold ONE LETTER ONLY, not a set of 3 letters.
You are trying to print them out using %s; but %s is for strings, not single characters.
Here is a corrected version of your program.
int main()
{
int i;
char* id[3]; // Declare strings, not characters.
id[0] = "id1"; // Initialize each with a string
id[1] = "id2";
id[2] = "id3";
for (i = 0; i < 3; ++i) // Set loop limit correctly.
{
printf("%s\n", id[i]);
}
}
You invoked undefined behavior by passing data having wrong type: %s expects an pointer to a null-terminated string while you passed id[i], whose type is char (expanded to int here).
You can use %c to display the values of implementation-defined values of multi-character character literals.
Also The loop range is wrong as #abelenky says.
#include <stdio.h>
int main()
{
int i;
char id[3]; ///sample data wanted to print
id[0] = 'id1';
id[1] = 'id2';
id[2] = 'id3';
for (i = 0; i < 3; ++i)
{
printf("%c", id[i]);
}
}
Or do you mean this?
#include <stdio.h>
int main()
{
int i;
const char* id[3]; ///sample data wanted to print
id[0] = "id1";
id[1] = "id2";
id[2] = "id3";
for (i = 0; i < 3; ++i)
{
printf("%s\n", id[i]);
}
}

convert char array into int 2d array in C language

I have a char array of indefinite number of "couples" composed by index and value, separated by semicolon. Each index is separated from its value by a comma.
Example:
char srt[50] = "1,3; 2,4; 0,-2; 3,11";
("index1, value1; index2, value2; ...")
I want to convert the char array into a 2d int array, like this:
int num[4][2] = {{1,3}, {2,4}, {0,-2}, {3,11}};
How?
Hoping not to get downvoted for doing you homework, but I just found some time to code something.
The approach is to first count the (possible) number of pairs (which is the number of semicolons + 1) in order to reserve a proper array.
Then, use a loop with strtok to separate the pairs and a sscanf(str, "%d,%d",..) to read in the values. Note that the actual number of pairs might be different from the maximum number of pairs due to failures on parsing a pair:
int main()
{
char srt[50] = "1,3; 2,4; 0,-2; 3,11";
char* p=srt;
size_t pairsCount = 1;
while (*p) {
if (*p++ == ';')
pairsCount++;
}
int pairs[pairsCount][2];
p = strtok(srt, ";");
pairsCount = 0;
while (p) {
int key = 0, value = 0;
if (sscanf(p, "%d,%d", &key, &value) == 2) {
pairs[pairsCount][0] = key;
pairs[pairsCount][1] = value;
pairsCount++;
}
p = strtok(NULL, ";");
}
for (int i=0; i<pairsCount; i++) {
printf("%d,%d\n", pairs[i][0], pairs[i][1]);
}
return 0;
}

C program - largest word in a 2d array string [duplicate]

I wrote a function that finds the longest string in a 2d array, it works, partially. My problem is that it takes the first longest string that it finds without checking the other ones.
For example, the following list of strings:
eke
em
ekeke
eme
e
ememeememe
emem
ekekee
eooeeeeefe
eede
My function catches "ekeke" (the third string from the list) as the longest instead of "ememeememe ".
Here is my function:
void length(char str[][MAX])
{
int i = 0;
for(i = 1; i < LEN; i++)
{
if(strlen(str[i]) > strlen(str[i-1]))
{
if(strlen(str[i]) > strlen(str[i+1]))
{
printf("%s", str[i]);
break;
}
}
}
}
LEN is a constant, his value is 10.
MAX is a constant, his value is 50.
The strings are given by the user.
Thanks.
You are only comparing the previous and next strings. You need to check the lengths of all the strings.
void length(char str[][MAX])
{
size_t longest = strlen(str[0]);
szie_t j = 0;
for(size_t i = 1; i < LEN; i++)
{
size_t len = strlen(str[i]);
if(longest < len)
{
longest = len;
j = i;
}
}
printf("%s", str[j]);
}
I am assuming you have at least 1 string and handle corner cases (if user inputs less than LEN strings etc -- depends on how you fill the str with strings).

Finding the longest string in a 2d array in C

I wrote a function that finds the longest string in a 2d array, it works, partially. My problem is that it takes the first longest string that it finds without checking the other ones.
For example, the following list of strings:
eke
em
ekeke
eme
e
ememeememe
emem
ekekee
eooeeeeefe
eede
My function catches "ekeke" (the third string from the list) as the longest instead of "ememeememe ".
Here is my function:
void length(char str[][MAX])
{
int i = 0;
for(i = 1; i < LEN; i++)
{
if(strlen(str[i]) > strlen(str[i-1]))
{
if(strlen(str[i]) > strlen(str[i+1]))
{
printf("%s", str[i]);
break;
}
}
}
}
LEN is a constant, his value is 10.
MAX is a constant, his value is 50.
The strings are given by the user.
Thanks.
You are only comparing the previous and next strings. You need to check the lengths of all the strings.
void length(char str[][MAX])
{
size_t longest = strlen(str[0]);
szie_t j = 0;
for(size_t i = 1; i < LEN; i++)
{
size_t len = strlen(str[i]);
if(longest < len)
{
longest = len;
j = i;
}
}
printf("%s", str[j]);
}
I am assuming you have at least 1 string and handle corner cases (if user inputs less than LEN strings etc -- depends on how you fill the str with strings).

Resources