Removing Garbage value in array in C - c

I have a garbage problem in my array in C, that I can't solve and I have used the memset function for this but this is not useful to me. how can I solve this problem. If I run this code in Code Block or other PC then this is not run completely.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
int main() {
clrscr();
int a, b, len = 0, x, i = 0, j, match, misMatch, gapPenalty, sim, m1, m2, m3;
char ch;
char *seq1 = (char *)malloc(100 * sizeof(char));
char *seq2 = (char *)malloc(100 * sizeof(char));
char *s1 = (char *)malloc(100 * sizeof(char));
char *s2 = (char *)malloc(100 * sizeof(char));
/*memset(seq1, 0, strlen(seq1) - 1);
memset(seq2, 0, strlen(seq2) - 1);
memset(s1, 0, strlen(s1) - 1);
memset(s2, 0, strlen(s2) - 1);*/
int **matrix;
int **back;
FILE *inputFile;
inputFile = fopen("in.txt", "r");
printf("Enter Match Point : ");
scanf("%d", &match);
printf("Enter Mismatch Point : ");
scanf("%d", &misMatch);
printf("Enter Gap Point : ");
scanf("%d", &gapPenalty);
while (fscanf(inputFile,"%s\n%s", seq1, seq2) != EOF);
a = strlen(seq1);
b = strlen(seq2);
for (j = 0; j <= strlen(seq2); j++) {
for (i = 0; i <= strlen(seq1); i++) {
if (i == 0 || j == 0) {
if (i == 0) {
matrix[j][i] = j * gapPenalty;
back[j][i] = 0;
}
if (j == 0) {
matrix[j][i] = i * gapPenalty;
back[j][i] = 0;
}
} else {
if (seq1[i - 1] == seq2[j - 1]) {
sim = match;
} else {
sim = misMatch;
}
m1 = matrix[j - 1][i - 1] + sim;
m2 = matrix[j - 1][i] + gapPenalty;
m3 = matrix[j][i - 1] + gapPenalty;
if (m1 > m2) {
if (m1 > m3) {
matrix[j][i] = m1;
back[j][i] = 1;
} else {
matrix[j][i] = m3;
back[j][i] = 3;
}
} else {
if (m2 > m3) {
matrix[j][i] = m2;
back[j][i] = 2;
} else {
matrix[j][i] = m3;
back[j][i] = 3;
}
}
}
}
}
printf("%s", seq1);
printf("\n");
printf("%s", seq2);
printf("\n");
if (a > b) {
len = a;
} else {
len = b;
}
for (x = 0; x < len; x++) {
if (back[b][a] == 1) {
s1[x] = seq1[a - 1];
s2[x] = seq2[b - 1];
a = a - 1;
b = b - 1;
} else if(back[b][a] == 2) {
s1[x] = seq1[a - 1];
s2[x] = '-';
a = a - 1;
} else {
s1[x] = '-';
s2[x] = seq2[b - 1];
b = b - 1;
}
}
for (j = 0; j <= strlen(seq2); j++) {
for (i = 0; i <= strlen(seq1); i++) {
printf("%d ", matrix[j][i]);
}
printf("\n");
}
printf("\n");
for (j = 0; j <= strlen(seq2); j++) {
for (i = 0; i <= strlen(seq1); i++) {
printf("%d ", back[j][i]);
}
printf("\n");
}
printf("\n");
printf("%s", s1);
printf("\n");
printf("%s", s2);
printf("\n");
free(s1);
free(s2);
free(matrix);
free(back);
getch();
return 0;
}

Use calloc(). calloc() initializes all the allocated memory to 0.
// sizeof (char), by definition, is 1
char *seq1 = calloc(100, 1);
char *seq2 = calloc(100, 1);
char *s1 = calloc(100, 1);
char *s2 = calloc(100, 1);
The immediate problem with your commented code is that you cannot apply strlen() to an uninitialized array. You should be using the correct size (which you just used a few statements before) instead
/*memset(seq1, 0, 100);
memset(seq2, 0, 100);
memset(s1, 0, 100);
memset(s2, 0, 100);*/

Related

C program can't figure out how to properly free mallocs

In the main function of my program I make a few malloc calls and what I think are the right free calls at the end. My address sanitizer is telling me that data is still leaking in line 206, which is:
names[size - 1] = malloc(17 * sizeof(char));
The problem is that if I include a free statement for names[size - 1], there is apparently data still leaking from it. I have no idea why. Here is the main:
int main(int argc, char** argv) {
if (argc - 1 != 1) {
printf("Invalid number of arguments\n");
return 0;
}
//get file, return if invalid path
FILE *file = fopen(argv[1], "r");
if (!file) {
printf("Invalid input\n");
return 0;
}
//make temp of circuit with struct directive
int scount = 0;
struct directive* temp = NULL;
int size = 2;
int icount = 0;
int ocount = 0;
int tcount = 0;
char dir[17];
char **names;
int *values;
//get INPUT info
fscanf(file, " %s", dir);
fscanf(file, "%d", &icount);
size += icount;
names = malloc(size * sizeof(char *));
names[0] = malloc(2 * sizeof(char)); //MALLOC
strcpy(names[0], "0");
names[1] = malloc(2 * sizeof(char)); //MALLOC
strcpy(names[1], "1");
int i;
for (i = 0; i < icount; i++) {
names[i + 2] = malloc(17 * sizeof(char));
fscanf(file, "%*[: ]%16s", names[i + 2]);
}
//get OUTPUT info
fscanf(file, " %s", dir);
fscanf(file, "%d", &ocount);
size += ocount;
names = realloc(names, size * sizeof(char *));
for (i = 0; i < ocount; i++) {
names[i + icount + 2] = malloc(17 * sizeof(char));
fscanf(file, "%*[: ]%16s", names[i + icount + 2]);
}
//get temp
struct directive step;
while (!feof(file)) {
int numInputs = 2, numOutputs = 1;
int sc = fscanf(file, " %s", dir);
if (sc != 1) {
break;
}
scount++;
step.n = 0;
step.s = 0;
strcpy(step.gate, dir);
if (strcmp(dir, "NOT") == 0) {
numInputs = 1;
}
if (strcmp(dir, "PASS") == 0) {
numInputs = 1;
}
if (strcmp(dir, "DECODER") == 0) {
fscanf(file, "%d", &numInputs);
step.n = numInputs;
numOutputs = pow(2, numInputs);
}
if (strcmp(dir, "MULTIPLEXER") == 0) {
fscanf(file, "%d", &numInputs);
step.s = numInputs;
numInputs = pow(2, numInputs);
}
step.inputs = malloc(numInputs * sizeof(int));
step.outputs = malloc(numOutputs * sizeof(int));
step.selectors = malloc(step.s * sizeof(int));
char v[17];
for (i = 0; i < numInputs; i++) {
fscanf(file, "%*[: ]%16s", v);
step.inputs[i] = indexOf(size, names, v);
}
for (i = 0; i < step.s; i++) {
fscanf(file, "%*[: ]%16s", v);
step.selectors[i] = indexOf(size, names, v);
}
for (i = 0; i < numOutputs; i++) {
fscanf(file, "%*[: ]%16s", v);
int idx = indexOf(size, names, v);
if (idx == -1) {
size++;
tcount++;
char **tmp = realloc(names, size * sizeof *tmp);
if (!tmp) abort(); // handle alloc failure
names = tmp;
names[size - 1] = malloc(17 * sizeof(char));
strcpy(names[size - 1], v);
step.outputs[i] = size - 1;
}
else {
step.outputs[i] = idx;
}
}
//add step to list of temp
if (!temp) {
temp = malloc(sizeof(struct directive));
} else {
temp = realloc(temp, scount * sizeof(struct directive));
}
temp[scount - 1] = step;
}
// initialize values array
values = malloc(size * sizeof(int));
resetValues(size, values);
while(1 < 2) {
//print inputs
for (i = 0; i < icount; i++) {
printf("%d ", values[i + 2]);
}
printf("|");
//run through temp, calculate outputs
for (i = 0; i < scount; i++) {
struct directive step = temp[i];
if (strcmp(step.gate, "NOT") == 0) {
NOT(values, step.inputs[0], step.outputs[0]);
}
if (strcmp(step.gate, "AND") == 0) {
AND(values, step.inputs[0], step.inputs[1], step.outputs[0]);
}
if (strcmp(step.gate, "OR") == 0) {
OR(values, step.inputs[0], step.inputs[1], step.outputs[0]);
}
if (strcmp(step.gate, "NAND") == 0) {
NAND(values, step.inputs[0], step.inputs[1], step.outputs[0]);
}
if (strcmp(step.gate, "NOR") == 0) {
NOR(values, step.inputs[0], step.inputs[1], step.outputs[0]);
}
if (strcmp(step.gate, "XOR") == 0) {
XOR(values, step.inputs[0], step.inputs[1], step.outputs[0]);
}
if (strcmp(step.gate, "PASS") == 0) {
PASS(values, step.inputs[0], step.outputs[0]);
}
if (strcmp(step.gate, "DECODER") == 0) {
DECODER(values, step.n, step.inputs, step.outputs);
}
if (strcmp(step.gate, "MULTIPLEXER") == 0) {
MUX(values, step.s, step.inputs, step.selectors, step.outputs[0]);
}
}
//print outputs
for (i = 0; i < ocount; i++) {
printf(" %d", values[icount + i + 2]);
}
printf("\n");
if (!incrementInputs(values, icount)) {
break;
}
}
for (i = 0; i < icount; i++) {
free(names[i + 2]);
}
for (i = 0; i < ocount; i++) {
free(names[i + icount + 2]);
}
for (int i = 0; i < scount; i++) {
free(temp[i].inputs);
free(temp[i].outputs);
free(temp[i].selectors);
}
free(names[0]);
free(names[1]);
//free(names[size-1]);
free(values);
free(temp);
free(names);
return 0;
}

implement strcat() function in C

I'm trying to implement strcat() in C but stuck on that the output result is repeated src.
here is my code.
void my_strcat(char des[], char src[]) {
int i = 0, j = 0;
while (des[i] != '\0')
i += 1;
while (src[j] != '\0') {
des[i + j] = src[j];
j += 1;
}
des[i + j] = '\0';
printf("%s", des);
}
int main() {
char des[1000], src[100];
for(int i = 0; i < 2; ++i) {
printf("src: ");
scanf("%s", src);
my_strcat(des, src);
}
printf("%s", des);
}
the output is not the same as I was expected before. It's like for example:
src: a
src: b
des: aabb
You probably want this:
#include <stdio.h>
#include <stdlib.h>
void my_strcat(char des[], const char src[]) { // better use const her
int i = 0, j = 0;
while (des[i] != '\0')
i += 1;
while (src[j] != '\0') {
des[i + j] = src[j];
j += 1;
}
des[i + j] = '\0';
// printf("%s", des); // dont print des here
}
int main() {
char des[1000];
char src[100];
des[0] = 0; // initialize des to a zero length string
for (int i = 0; i < 2; ++i) {
printf("src: ");
scanf("%s", src);
my_strcat(des, src);
}
printf("%s", des); // print the destination
}

Checking NULL pointer segmentation fault in C

I have to split an initial char and create a list of said char which has to end with a NULL so i can iterate over in the main without knowing list size. The problem is that i get a seg fault whenever i try to check if last element is NULL. i am sorry i am still trying to learn both C and english. Thank you all
#include <stdlib.h>
#include <stdio.h>
char **split(const char *s) {
char **split;
unsigned m_size = 0, c_size, i, j, k;
// get s size
for (i = 0; s[i] != '\0'; i++) {
if (s[i] == ' ') {
m_size++;
}
}
m_size++;
split = (char**) malloc(sizeof(char) * (m_size + 1));
int sizes[m_size];
c_size = 0;
// get s words size
for (i = 0, j = 0; s[i] != '\0'; i++) {
if (s[i] == ' ') {
c_size++;
sizes[j] = c_size;
c_size = 0;
j++;
} else {
c_size++;
}
}
sizes[j] = c_size;
for (i = 0; i < m_size; i++) {
split[i] = (char *) malloc(sizeof(char) * sizes[i]);
}
split[i] = NULL;
for (i = 0, j = 0, k = 0; s[i] != '\0'; i++) {
if (s[i] != ' ') {
split[j][k] = s[i];
k++;
} else {
split[j][k] = '\0';
j++;
k = 0;
}
}
return split;
}
int main() {
char s[19] = "hello how are you?";
char **splitted;
unsigned i;
splitted = split(s);
if (splitted == NULL) {
return 1;
}
for (i = 0; splitted[i]!=NULL; i++) {
printf("%s\n", splitted[i]);
}
return 0;
}
EDIT
#include <stdlib.h>
#include <stdio.h>
char **split(const char *s) {
char **r;
unsigned word_size = 0;
unsigned list_size = 0, i, j, k;
// get s size
for (i = 0; s[i] != '\0'; i++) {
if (s[i] != ' ') {
word_size++;
} else {
if (word_size > 0) {
list_size++;
word_size = 0;
}
}
}
list_size++;
r = malloc(sizeof(*r) * (list_size + 1));
int char_sizes[list_size];
for (i = 0; i < list_size; char_sizes[i] = 0, i++);
// get s words size
for (i = 0, j = 0; s[i] != '\0'; i++) {
if (s[i] != ' ') {
char_sizes[j]++;
} else {
if (char_sizes[j] > 0) {
j++;
}
}
}
for (i = 0; i < list_size; i++) {
r[i] = malloc(sizeof(char) * char_sizes[i]);
}
r[i] = NULL;
for (i = 0, j = 0, k = 0; s[i] != '\0'; i++) {
if (s[i] != ' ') {
r[j][k] = s[i];
k++;
} else {
if (k > 0) {
r[j][k] = '\0';
j++;
k = 0;
}
}
}
return r;
}
void destroy(char **list) {
unsigned i;
for (i = 0; list[i] != NULL; i++) {
free(list[i]);
}
free(list);
}
int main() {
char s[100] = " hello guys how are? you,d 31 3 ";
char **splitted;
unsigned i;
splitted = split(s);
if (splitted == NULL) {
return 1;
}
for (i = 0; splitted[i]!=NULL; i++) {
printf("%s", splitted[i]);
}
destroy(splitted);
return 0;
}
ok guys i followed your tips and i edited my code. leaving this here if someone wants to point out other errors i will appreciate. now it should work even with multiple spaces. thanks to all
Your are requesting an "array" of pointers to char, but you are allocating an "array" of chars:
split = (char**) malloc(sizeof(char) * (m_size + 1));
should become
split = malloc(sizeof(char*) * (m_size + 1));
Note the sizeof(char*). BTW: Note that in C, you should not cast the result of malloc as explained in this SO post.

Adding two really large numbers in C

I am trying to add two really large numbers (say 30 digit long) in C. Here is my code:
#include <stdio.h>
#include <string.h>
int main()
{
char a[30] =
{
'1','1','1','1','1','1','1','1','1','1','1','1','1','1','1',
'1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'
. };
b[30] =
{
'8','8','8','8','8','8','8','8','8','8','8','8','8','8','8',
'8','8','8','8','8','8','8','8','8','8','8','8','8','8','8'
};
int i, j, k, carry = 0, sum[1001];
if(strlen(a) >= strlen(b))
{
k = strlen(a);
}
else
{
k = strlen(b);
}
for(i = strlen(a); i > 0; i--)
{
for(j = strlen(b); j > 0; j--)
{
sum[k] = (a[i]-'0') + (b[j]-'0') + carry;
carry = sum[k]/10;
k--;
}
}
for(i = 0; i < k; i++)
{
printf("%d", sum[i]);
}
printf("\n");
return 0;
}
but it gives me no answer at all. What is wrong with it?
Small change to the code above to take care of the last trailing carry value if it > 0:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
int temp = 0;
char *fp ;
char *sp ;
char bigger = '\n';
char a[10] =
{
'1','2','3','4','5','6','7','8','9','1'
};
char b[10] =
{
'9','8','9','8','9','8','9','8','9','8'
};
int i, c, j, k, carry = 0, sum[1001] = {0};
if(sizeof(a) > sizeof(b))
{
k = sizeof(a);
j = sizeof(b);
bigger = 'a';
}
else
{
k = sizeof(b);
j = sizeof(a);
bigger = 'b';
}
c = k;
fp = malloc(k);
sp = malloc(j);
if (bigger == 'a')
{
strncpy(fp, a, k);
strncpy(sp, b, j);
}
else
{
strncpy(fp, b, k);
strncpy(sp, a, j);
}
for(i = strlen(fp); i > 0; i--,j--)
{
if(j>0 )
{
temp = *(fp+i-1)-'0' + *(sp+j-1)-'0' + carry;
if(temp < 10)
{
sum[k] += temp;
carry = 0;
}
else
{
sum[k] += temp%10;
carry = temp/10;
}
}
else
{
temp = *(fp+i-1)-'0' + carry;
if(temp < 10)
{
sum[k] += temp;
carry = 0;
}
else
{
sum[k] += temp%10;
carry = temp/10;
}
}
k--;
}
if(carry > 0)
printf("%d", carry);
for(i = 1; i <= c; i++)
{
printf("%d", sum[i]);
}
printf("\n");
return 0;
}
This should work. I changed the way your loops should work and also added some checks to ensure alignment and consistency in case the length of the large numbers change.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int temp = 0;
char *fp ;
char *sp ;
char bigger = '\n';
char a[30] =
{'1','1','1','1','1','1',
'1','1','1','1','1','1',
'1','1','1','1','1','1','1','1','1','1','1','1','1',
'1','1','1','1','1'
};
char b[30] =
{
'8','8','8','8','8','8','8','8','8','8','8','8','8','8',
'8','8','8','8','8','8','8','8','8','8','8','8','8','8',
'8','8'
};
int i, c, j, k, carry = 0, sum[1001] = {0};
if(sizeof(a) > sizeof(b))
{
k = sizeof(a);
j = sizeof(b);
bigger = 'a';
}
else
{
k = sizeof(b);
j = sizeof(a);
bigger = 'b';
}
c = k;
fp = malloc(k);
sp = malloc(j);
if (bigger == 'a')
{
strncpy(fp, a, k);
strncpy(sp, b, j);
}
else
{
strncpy(fp, b, k);
strncpy(sp, a, j);
}
for(i = strlen(fp); i > 0; i--,j--)
{
if(j>0 )
{
temp = *(fp+i-1)-'0' + *(sp+j-1)-'0' + carry;
if(temp < 10)
{
sum[k] += temp;
carry = 0;
}
else
{
sum[k] += temp%10;
carry = temp/10;
}
}
else
{
temp = *(fp+i-1)-'0' + carry;
if(temp < 10)
{
sum[k] += temp;
carry = 0;
}
else
{
sum[k] += temp%10;
carry = temp/10;
}
}
k--;
}
if(carry > 0)
printf("%d", carry);
for(i = 1; i <= c; i++)
{
printf("%d", sum[i]);
}
printf("\n");
return 0;
}

Not sure why int value is not what it is supposed to be

I'm solving this problem : https://www.hackerrank.com/challenges/structuring-the-document/problem
When I run my program on my IDE (XCode) I can see that word_count int 7428912 is not what it is supposed to be for any input. I am not sure why. I know that I am accessing out of bounds array index but I need someone to show me where exactly. The program outputs correctly and then gives an error. Thread 1: EXC_BAD_ACCESS (code=1, address=0x73696870)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAX_CHARACTERS 1005
#define MAX_PARAGRAPHS 5
struct word {
char* data;
};
struct sentence {
struct word* data;
int word_count;//denotes number of words in a sentence
};
struct paragraph {
struct sentence* data ;
int sentence_count;//denotes number of sentences in a paragraph
};
struct document {
struct paragraph* data;
int paragraph_count;//denotes number of paragraphs in a document
};
#include <ctype.h>
struct document get_document(char* text) {
int spaces = 0, periods = 0, newlines = 0;
for(int i = 0; i < strlen(text); i++)
if(text[i] == ' ')
spaces++;
else if(text[i] == '.')
periods++;
else if(text[i] == '\n')
newlines++;
struct document doc;
doc.paragraph_count = newlines + 1;
doc.data = malloc((newlines + 1) * sizeof(struct paragraph));
int inBetweenPeriods = 0, j = 0;
struct paragraph para[doc.paragraph_count];
for(int i = 0; i < doc.paragraph_count; i++) {
for(; j < strlen(text); )
if(text[j] == '.') {
inBetweenPeriods++;
j++;
}
else if(text[j] == '\n' || j == strlen(text) - 1) {
para[i].sentence_count = inBetweenPeriods;
j++;
break;
}
else
j++;
para[i].data = malloc((inBetweenPeriods) * sizeof(struct sentence));
inBetweenPeriods = 0;
}
struct sentence sen[periods];
int sp[periods];
for(int j = 0; j < periods; j++)
sp[j] = 0;
int beg = 0;
int ij = 0;
for(int j = 0; j < strlen(text); j++) {
if(text[j] == '.') {
for(int k = beg; k < j; k++)
if(text[k] == ' ')
sp[ij]++;
ij++;
beg = j + 1;
}
}
for(int i = 0; i < periods; i++) {
sen[i].word_count = sp[i] + 1;//spaces + 1;
sen[i].data = malloc((sp[i] + 1) * sizeof(struct word));
}
struct word word[spaces + periods];
int start = 0, k = 0, wordsub = 0, sensub = 0, parasub = 0, docsub = 0, wordno = 0, parano = 0;
for(int i = 0; i < strlen(text); i++) {
if(text[i] == ' ' || text[i] == '.') {
word[wordsub].data = malloc((i - start) * sizeof(char) + 1);
for(int j = start; j < i; j++)
word[wordsub].data[k++] = text[j];
word[wordsub].data[k++] = '\0';
k = 0;
if(i < strlen(text) - 1 && text[i + 1] == '\n')
start = i + 2;
else
start = i + 1;
if(text[i] == ' ') {
sen[sensub].data[wordno] = word[wordsub];
wordno++; //wordno can be 0 or 1
}
if(i != strlen(text) - 1 && isalpha(text[i + 1]) && text[i] == '.') {
sen[sensub].data[wordno] = word[wordsub];
wordno = 0;
para[parasub].data[parano] = sen[sensub];
sensub++;
parano++;
}
if( (i != strlen(text) - 1 && text[i + 1] == '\n') || i == strlen(text) - 1) {
sen[sensub].data[wordno] = word[wordsub];
wordno = 0;
para[parasub].data[parano++] = sen[sensub];
parano = 0;
doc.data[docsub++] = para[parasub];
parasub++;
sensub++;
}
wordsub++;
}
}
return doc;
}
struct word kth_word_in_mth_sentence_of_nth_paragraph(struct document Doc, int k, int m, int n) {
return Doc.data[n - 1].data[m - 1].data[k - 1];
}
struct sentence kth_sentence_in_mth_paragraph(struct document Doc, int k, int m) {
return Doc.data[m - 1].data[k - 1];
}
struct paragraph kth_paragraph(struct document Doc, int k) {
return Doc.data[k - 1];
}
void print_word(struct word w) {
printf("%s", w.data);
}
void print_sentence(struct sentence sen) {
for(int i = 0; i < sen.word_count; i++) {
print_word(sen.data[i]);
if (i != sen.word_count - 1) {
printf(" ");
}
}
}
void print_paragraph(struct paragraph para) {
for(int i = 0; i < para.sentence_count; i++){
print_sentence(para.data[i]);
printf(".");
}
}
void print_document(struct document doc) {
for(int i = 0; i < doc.paragraph_count; i++) {
print_paragraph(doc.data[i]);
if (i != doc.paragraph_count - 1)
printf("\n");
}
}
char* get_input_text() {
int paragraph_count;
scanf("%d", &paragraph_count);
char p[MAX_PARAGRAPHS][MAX_CHARACTERS], doc[MAX_CHARACTERS];
memset(doc, 0, sizeof(doc));
getchar();
for (int i = 0; i < paragraph_count; i++) {
scanf("%[^\n]%*c", p[i]);
strcat(doc, p[i]);
if (i != paragraph_count - 1)
strcat(doc, "\n");
}
char* returnDoc = (char*)malloc((strlen (doc)+1) * (sizeof(char)));
strcpy(returnDoc, doc);
return returnDoc;
}
int main()
{
char* text = get_input_text();
struct document Doc = get_document(text);
int q;
scanf("%d", &q);
while (q--) {
int type;
scanf("%d", &type);
if (type == 3){
int k, m, n;
scanf("%d %d %d", &k, &m, &n);
struct word w = kth_word_in_mth_sentence_of_nth_paragraph(Doc, k, m, n);
print_word(w);
}
else if (type == 2) {
int k, m;
scanf("%d %d", &k, &m);
struct sentence sen= kth_sentence_in_mth_paragraph(Doc, k, m);
print_sentence(sen);
}
else{
int k;
scanf("%d", &k);
struct paragraph para = kth_paragraph(Doc, k);
print_paragraph(para);
}
printf("\n");
}
}
I solved it like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAX_CHARACTERS 1005
#define MAX_PARAGRAPHS 5
struct word {
char* data;
};
struct sentence {
struct word* data;
int word_count;//denotes number of words in a sentence
};
struct paragraph {
struct sentence* data ;
int sentence_count;//denotes number of sentences in a paragraph
};
struct document {
struct paragraph* data;
int paragraph_count;//denotes number of paragraphs in a document
};
#include <ctype.h>
struct document get_document(char* text) {
int spaces = 0, periods = 0, newlines = 0;
for(int i = 0; i < strlen(text); i++)
if(text[i] == ' ')
spaces++;
else if(text[i] == '.')
periods++;
else if(text[i] == '\n')
newlines++;
struct document doc;
doc.paragraph_count = newlines + 1;
doc.data = malloc((newlines + 1) * sizeof(struct paragraph));
int inBetweenPeriods = 0, j = 0;
struct paragraph para[doc.paragraph_count];
for(int i = 0; i < doc.paragraph_count; i++) {
for(; j < strlen(text);)
if(text[j] == '.')
{ inBetweenPeriods++;j++;}
else if(text[j] == '\n' || j == strlen(text) - 1)
{j++;break;}else j++;
para[i].sentence_count = inBetweenPeriods;
para[i].data = malloc((inBetweenPeriods) * sizeof(struct sentence));
inBetweenPeriods = 0;
}
struct sentence sen[periods];
int sp[periods];
for(int j = 0; j < periods; j++)
sp[j] = 0;
int beg = 0;
int ij = 0;
for(int j = 0; j < strlen(text); j++) {
if(text[j] == '.') {
for(int k = beg; k < j; k++)
if(text[k] == ' ')
sp[ij]++;
ij++;
beg = j + 1;
}
}
for(int i = 0; i < periods; i++) {
sen[i].word_count = sp[i] + 1;//spaces + 1;
sen[i].data = malloc((sp[i] + 1) * sizeof(struct word));
}
struct word word[spaces + periods];
int start = 0, k = 0, wordsub = 0, sensub = 0, parasub = 0, docsub = 0, wordno = 0, parano = 0;
for(int i = 0; i < strlen(text); i++) {
if(text[i] == ' ' || text[i] == '.') {
word[wordsub].data = malloc((i - start) * sizeof(char) + 1);
for(int j = start; j < i; j++)
word[wordsub].data[k++] = text[j];
word[wordsub].data[k++] = '\0';
k = 0;
if(i < strlen(text) - 1 && text[i + 1] == '\n')
start = i + 2;
else
start = i + 1;
if(text[i] == ' ') {
sen[sensub].data[wordno] = word[wordsub];
wordno++; //wordno can be 0 or 1
}
if(i != strlen(text) - 1 && isalpha(text[i + 1]) && text[i] == '.') {
sen[sensub].data[wordno] = word[wordsub];
wordno = 0;
para[parasub].data[parano] = sen[sensub];
sensub++;
parano++;
}
if( (i != strlen(text) - 1 && text[i + 1] == '\n') || i == strlen(text) - 1) {
sen[sensub].data[wordno] = word[wordsub];
wordno = 0;
para[parasub].data[parano++] = sen[sensub];
parano = 0;
doc.data[docsub++] = para[parasub];
parasub++;
sensub++;
}
wordsub++;
}
}
return doc;
}
struct word kth_word_in_mth_sentence_of_nth_paragraph(struct document Doc, int k, int m, int n) {
return Doc.data[n - 1].data[m - 1].data[k - 1];
}
struct sentence kth_sentence_in_mth_paragraph(struct document Doc, int k, int m) {
return Doc.data[m - 1].data[k - 1];
}
struct paragraph kth_paragraph(struct document Doc, int k) {
return Doc.data[k - 1];
}
void print_word(struct word w) {
printf("%s", w.data);
}
void print_sentence(struct sentence sen) {
for(int i = 0; i < sen.word_count; i++) {
print_word(sen.data[i]);
if (i != sen.word_count - 1) {
printf(" ");
}
}
}
void print_paragraph(struct paragraph para) {
for(int i = 0; i < para.sentence_count; i++){
print_sentence(para.data[i]);
printf(".");
}
}
void print_document(struct document doc) {
for(int i = 0; i < doc.paragraph_count; i++) {
print_paragraph(doc.data[i]);
if (i != doc.paragraph_count - 1)
printf("\n");
}
}
char* get_input_text() {
int paragraph_count;
scanf("%d", &paragraph_count);
char p[MAX_PARAGRAPHS][MAX_CHARACTERS], doc[MAX_CHARACTERS];
memset(doc, 0, sizeof(doc));
getchar();
for (int i = 0; i < paragraph_count; i++) {
scanf("%[^\n]%*c", p[i]);
strcat(doc, p[i]);
if (i != paragraph_count - 1)
strcat(doc, "\n");
}
char* returnDoc = (char*)malloc((strlen (doc)+1) * (sizeof(char)));
strcpy(returnDoc, doc);
return returnDoc;
}
int main()
{
char* text = get_input_text();
struct document Doc = get_document(text);
int q;
scanf("%d", &q);
while (q--) {
int type;
scanf("%d", &type);
if (type == 3){
int k, m, n;
scanf("%d %d %d", &k, &m, &n);
struct word w = kth_word_in_mth_sentence_of_nth_paragraph(Doc, k, m, n);
print_word(w);
}
else if (type == 2) {
int k, m;
scanf("%d %d", &k, &m);
struct sentence sen= kth_sentence_in_mth_paragraph(Doc, k, m);
print_sentence(sen);
}
else{
int k;
scanf("%d", &k);
struct paragraph para = kth_paragraph(Doc, k);
print_paragraph(para);
}
printf("\n");
}
}

Resources