I have two dinamicaly created arrays:
int *sifre = malloc(brkomp* sizeof(int));
int *faktori = malloc(brkomp * sizeof(int));
and next part of code:
do {
int i = 0;
while ((podatak[i] = getchar()) != ' ')
{
i++;
}
sifre[j] = atoi(podatak);
for (i = 0; i < 100; i++)
{
podatak[i] = ' ';
}
i = 0;
while ((end = podatak[i] = getchar()) != ' ' && end != '\n')
{
i++;
}
faktori[k] = atoi(podatak);
for (i = 0; i < 100; i++)
{
podatak[i] = ' ';
}
j++;
k++;
} while (end != '\n');
Input at console is like this:
23 2 257 1
When I debug after first iteration values of sifre[j] and faktori[k] are 23 and 2 respectively.
But after second iteration values are still the same. I expect 257 and 1.
Why this doesn't work?
This works with gcc 4.9.3:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int i, j, k, end;
char podatak[100];
int *sifre = malloc(100 * sizeof(int));
int *faktori = malloc(100 * sizeof(int));
j = k = 0;
do {
for (i = 0; (podatak[i] = getchar()) != ' '; ++i)
;
podatak[i] = '\0';
sifre[j++] = atoi(podatak);
for (i = 0; (end = podatak[i] = getchar()) != ' ' && end != '\n'; ++i)
;
podatak[i] = '\0';
faktori[k++] = atoi(podatak);
}
while (end != '\n');
}
Related
This is the challenge I'm trying to solve:
https://www.hackerrank.com/challenges/querying-the-document/
So far I have made progress but I am stuck at a Segmentation Fault and I can't figure out why.
The following is an abridged version of the whole source code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char**** 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++;
}
char** para[periods + 1]; // each paragraph stores that many sentences
char* senten[spaces + 1]; // each sentence stores that many words
char*** doc[newlines + 1]; // each document stores that many paragraphs
int start = 0, k = 0, m, p = 0, x = 0;
for(int i = 0; i != strlen(text); i++) {
if(text[i] == ' ' || text[i] == '.') { // space or period means there was a word before it
senten[k] = (char*) malloc(sizeof(char) * (i - start)); // store each word
m = 0;
for(int j = start; j < i; )
senten[k][m++] = text[j++];
senten[k][m++] = '\0'; // append a '\0' to end the string
if(text[i + 1] == '\n') { // newline means that a new paragraph is starting
para[p] = senten; // store pointer to sentence in para
while(k)
senten[k--] = NULL; // don't need now
start = i + 2;
p++;
}
else
start = i + 1;
k++;
}
if(i == strlen(text) - 1) { // end of file
doc[x++] = para; // store pointer to paragraph in doc
while(p)
para[p--] = NULL; // don't need
}
}
return doc;
}
int main()
{
char* text = "Hello World.\nHi.Bye.";
char**** doc = get_document(text);
printf("%s",doc[0][0][0]); // should print "Hello"
return 0;
}
In short the program is supposed to take a char* and output a char****.
Example:
If char * text = "Hello World.\nHi.Bye.";
Then char **** doc = {{{"Hello","World"}},{{"Hi"},{"Bye"}}};
You return the local variable in get_document function:
char** para[periods + 1]; // each paragraph stores that many sentences
char* senten[spaces + 1];
char*** doc[newlines + 1];
...
return doc;
It's bad idea, Because out of get_document function, the variable doc maybe does not exist.
You should use:
char*** para = malloc((periods + 1) * sizeof(char **));
char** senten = malloc((spaces + 1) * sizeof(char *));
char**** doc = malloc((newlines + 1)*sizeof(char ***));
This is how I modified my code. Now it passes all the test cases.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
char**** get_document(char* newtext) {
int spaces = 0, periods = 0, newlines = 0;
for(int i = 0; i != strlen(newtext); i++) {
if(newtext[i] == ' ')
spaces++;
else if(newtext[i] == '.')
periods++;
else if(newtext[i] == '\n')
newlines++;
}
char*** para = malloc((periods + 1) * sizeof(char **));
char** senten = malloc((spaces + 1) * sizeof(char *));
char**** doc = malloc((newlines + 1) * sizeof(char ***));
int start = 0, k = 0, m, p = 0, x = 0, f = 0, pp = 0;
int pcount = 0;
for(int i = 0; i != strlen(newtext); i++) {
if(newtext[i] == '.') pcount++;
if(newtext[i] == ' ' || newtext[i] == '.') { // space or period means there was a word before it
senten[k] = (char*) malloc(sizeof(char) * (i - start) + 1); // store each word
m = 0;
for(int j = start; j < i; )
senten[k][m++] = newtext[j++];
senten[k][m++] = '\0'; // append a '\0' to end the string
k++;
if(i != strlen(newtext) && newtext[i + 1] == '\n') // newline means that a new paragraph is starting
start = i + 2;
else
start = i + 1;
if(i != strlen(newtext) && isalpha(newtext[i + 1]) && newtext[i] == '.') {
para[p++] = senten;
senten = malloc((spaces + 1) * sizeof(char *));
k = 0;
}
if((i != strlen(newtext) && newtext[i + 1] == '\n') || i + 1 == strlen(newtext)) {
para[p++] = senten;
senten = malloc((spaces + 1) * sizeof(char *));
k = 0;
doc[f++] = &(para[pp]);
pp += pcount;
pcount = 0;
}
}
}
return doc;
}
int main()
{
char* newtext = "Hello World.\nHi.Bye.\nWow.";
char**** doc = get_document(newtext);
printf("%s\n", doc[0][0][0]);
printf("%s\n", doc[0][0][1]);
printf("%s\n", doc[1][0][0]);
printf("%s\n", doc[1][1][0]);
printf("%s\n", doc[2][0][0]);
return 0;
}
Currently struggling to solve ex 1.21. The task is: Write a program entab that replaces strings of blanks by the minimum number
of tabs and blanks to achieve the same spacing. Use the same tab stops as for detab . When
either a tab or a single blank would suffice to reach a tab stop, which should be given
preference?
Below is my code i have made so far. I have no problems typing the amount of spaces less than tabsize but when it is bigger than that I get segmentation fault. Could anyone help me, please?
#include <stdio.h>
#include <ctype.h>
#define TAB 8
#define MAXLINE 1000
int getmine(char s[], int lim);
int entab(char output[], int pos, int space);
int main()
{
char line[MAXLINE], output[MAXLINE];
int i;
while ((i = getmine(line, MAXLINE)) > 0)
{
int space = 0;
int pos = 0;
int count = 0;
while (line[count] != '\n')
{
if (line[count] != ' ')
{
space = 0;
output[count] = line[count];
}
else if (line[count] == ' ')
{
pos = count - space;
space++;
if (line[count + 1] != ' ')
{
if (space > TAB)
{
int z = entab(output, pos, space);
count = z;
}
else
{
for (int a = 0; a < space; a++)
output[pos + a] = ' ';
}
}
}
count++;
}
if (line[count] == '\n')
{
output[count] = line[count];
count++;
}
output[count] = '\0';
printf("%s", output);
}
}
int getmine(char s[],int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n')
{
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
int entab(char output[], int pos, int space)
{
int nTabs = 0;
int nSpaces = 0;
int x = TAB - (pos % TAB);
if (x > 0)
{
output[pos] = '\t';
space = space - x;
nTabs = space / TAB;
nSpaces = space % TAB;
for (int a = 0; a < nTabs; a++)
output[pos + 1 + a] = '\t';
for (int b = 0; b < nSpaces; b++)
output[pos + 1 + nTabs + b] = ' ';
return pos + nTabs + nSpaces + 1;
}
else if (x == 0)
{
nTabs = space / TAB;
nSpaces = space % TAB;
for (int a = 0; a < nTabs; a++)
output[pos + a] = '\t';
for (int b = 0; b < nSpaces; b++)
output[pos + nTabs + b] = ' ';
return pos + nTabs + nSpaces;
}
}
Because the whitespace sequences of 8 characters are replaced by a single character (the tab), the number of read bytes from the input do not match to the written bytes in the output. A simple solution for this, is to simply keep track of two variables, one for the read bytes from the input, and one for the written bytes to the output. You could do this somewhat neater with pointers, though if you are following the book in a linear fashion, IIRC pointers are introduced later on.
Untested (namely for demonstrative purposes) code below.
NOTE: I took some liberties in reformatting your code for brevity.
#include <stdio.h>
#include <ctype.h>
#define TAB 8
#define MAXLINE 1000
int getmine(char s[], int lim);
int entab(char output[], int pos, int space);
int main()
{
char line[MAXLINE], output[MAXLINE];
int i;
while ((i = getmine(line, MAXLINE)) > 0) {
int space = 0;
int pos = 0;
int read_bytes = 0;
int write_bytes = 0;
while(read_bytes < i) {
if (line[read_bytes] != ' ') {
space = 0;
output[write_bytes++] = line[read_bytes];
}
else if (line[read_bytes] == ' ') {
space++;
if (line[read_bytes + 1] != ' ') {
if (space > TAB) {
write_bytes += entab(output, write_bytes, space);
} else {
for (int i = 0; i < space; i++)
output[write_bytes++] = ' ';
}
}
}
read_bytes++;
}
if (line[read_bytes] == '\n') {
output[write_bytes++] = line[read_bytes];
}
output[write_bytes] = '\0';
printf("%s", output);
}
}
int getmine(char s[],int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
int entab(char output[], int pos, int space)
{
int nTabs = 0;
int nSpaces = 0;
int x = TAB - (pos % TAB);
if (x > 0) {
output[pos] = '\t';
space = space - x;
nTabs = space / TAB;
nSpaces = space % TAB;
for (int i = 0; i < nTabs; i++)
output[pos + 1 + i] = '\t';
for (int i = 0; i < nSpaces; i++)
output[pos + 1 + nTabs + i] = ' ';
return nTabs + nSpaces + 1;
} else if (x == 0) {
nTabs = space / TAB;
nSpaces = space % TAB;
for (int i = 0; i < nTabs; i++)
output[pos + i] = '\t';
for (int i = 0; i < nSpaces; i++)
output[pos + nTabs + i] = ' ';
}
return nTabs + nSpaces;
}
In my solution I used external variables for index counter of output line.
And I made separated function for converting input array to output array.
#include <stdio.h>
#define TAB 8
#define MAX 100;
int j; //counter of newline
char line[MAX];
char newline[MAX];
int getter(void);
void converter(void);
int entab(int space_counter, int line_index);
int main()
{
extern char line[];
extern char newline[];
int len;
while ((len = getter()) > 0) {
converter();
printf("%s", newline);
}
}
int getter()
{
int c;
int i;
i = 0;
while ((c = getchar()) != EOF && c != '\n' && i < 30-1) {
line[i] = c;
++i;
}
if (c == '\n') {
line[i] = c;
++i;
}
line[i] = '\0';
return i;
}
void converter(void)
{
extern int j;
extern char line[];
extern char newline[];
int space_counter;
int i;
i = j = 0;
space_counter = 0;
while (line[i] != '\0') {
while (line[i] == ' ') {
space_counter++;
i++;
}
if (space_counter > 0) {
j = entab(space_counter, i);
space_counter = 0;
}
else {
newline[j] = line[i];
j++;
i++;
}
}
newline[j] = '\0';
}
int entab(int space_counter, int end_point)
{
extern int j;
extern char newline[];
int new_index;
int start_point;
int tab_qty;
int space_qty;
start_point = end_point - space_counter;
tab_qty = end_point / TAB - start_point / TAB;
if (TAB > start_point)
space_qty = space_counter;
else
space_qty = end_point % TAB;
for (tab_qty; tab_qty > 0; tab_qty--) {
newline[j] = '\t';
j++;
}
for (space_qty; space_qty > 0; space_qty--) {
newline[j] = '|';
j++;
}
return new_index = j;
}
I need to tokenize a string from an array, i need just three words and ignore all tabs '\t' and spaces ' '
the array line[] is just a test case.
I debugged mine, the first array (supposed to carry only the first word) got filled by spaces & letters from 3 words, not stopping after the first word when a tab or space is met. BTW my program crashed. i suspect getting out of array bounds maybe.
What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char line[] = " CLOOP LDA buffer,x";
char array1[20] ="";
char array2[20] ="";
char array3[20] ="";
int i = 0;
for( i ; i<strlen(line) ; i++)
{
while ( (line[i] != ' ') && (line[i] != '\t'))
{
if(array1[0] == '\0')
{
int j = 0;
while(line[i] != ' ' && line[i] != '\t')
{
array1[j] = line[i];
i++;
j++;
}
}
if(array2[0] =='\0');
{
int k = 0;
while(line[i] != ' ' && line[i] != '\t')
{
array2[k] = line[i];
i++;
k++;
}
}
if(array3[0] == '\0')
{
int g = 0;
while(line[i] != ' ' && line[i] != '\t')
{
array3[g] = line[i];
i++;
g++;
}
}
}
}
printf("array 1: %s\n array2: %s\n array3: %s\n", array1, array2, array3);
return(0);
}
You are over-complicating things. First of all it is difficult to feed all 3 arrays at the same time. The processing for one token should be completely finished before moving to the other token.
I would propose to "eat" all the white spaces before starting to process a token.
That is done by:
// skip leading delimiters
if( skip_leading_delimiters )
{
if( is_delimiter( delimiters, line[i]) ) continue;
skip_leading_delimiters = 0;
}
After token is processes you can move to the next token and process it. I tried to preserve your concept and approach as much as I could. The amount of while loops has been reduced to 0 since // skip leading delimiters section takes care of it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int is_delimiter(const char * delimiters, char c) // check for a delimiter
{
char *p = strchr (delimiters, c); // if not NULL c is separator
if (p) return 1; // delimeter
else return 0; // not a delimeter
}
int main()
{
char line[] = " CLOOP LDA buffer,x";
char array1[20];
char array2[20];
char array3[20];
int con1 = 1;
int con2 = 0;
int con3 = 0;
int con1s = 0;
int con2s = 0;
int con3s = 0;
int i = 0;
int j = 0;
int skip_leading_delimiters = 1;
char * delimiters = " \b";
for(i = 0; i < strlen(line); i++)
{
// skip leading delimiters
if( skip_leading_delimiters )
{
if( is_delimiter( delimiters, line[i]) ) continue;
skip_leading_delimiters = 0;
}
if(con1)
{
if(line[i] != ' ' && line[i] != '\t')
{
array1[j] = line[i];
j++;
array1[j] = 0;
con1s = 1;
}
else
{
if(con1s)
{
con1 = 0;
con2 = 1;
skip_leading_delimiters = 1;
j = 0;
}
continue;
}
}
if(con2)
{
if(line[i] != ' ' && line[i] != '\t')
{
array2[j] = line[i];
j++;
array2[j] = 0;
con2s = 1;
}
else
{
con2 = 0;
con3 = 1;
skip_leading_delimiters = 1;
j = 0;
continue;
}
}
if(con3)
{
if(line[i] != ' ' && line[i] != '\t')
{
array3[j] = line[i];
j++;
array3[j] = 0;
con3s = 1;
}
else
{
con3 = 0;
j = 0;
continue;
}
}
}
printf(" array1: %s\n array2: %s\n array3: %s\n", array1, array2, array3);
return(0);
}
Output:
array1: CLOOP
array2: LDA
array3: buffer,x
Eg: input: char *str1 = "the are all is well";
char *str2 = "is who the";
output: common words in two given strings, return 2D array of strings.
#define SIZE 31
char ** commonWords(char *str1, char *str2) {
int i,j=0,count1,count2,k=0,a,b,m=0,n;
char str3[100][100], str4[100][100];
char **output;
output = (char **)malloc(SIZE*sizeof(char*));
if (str1 == NULL || str2 == NULL)
{
return NULL;
}
for (i = 0; str1[i] != '\0'; i++)
{
if (str1[i] != ' ')
{
str3[j][k++] = str1[i];
}
else
{
str3[j][k++] = '\0';
j++;
k = 0;
}
}
str3[j][k++] = '\0';
count1 = j > 0 ? j + 1 : j;
j = k = 0;
for (i = 0; str2[i] != '\0'; i++)
{
if (str2[i] != ' ')
{
str4[j][k++] = str2[i];
}
else
{
str4[j][k++] = '\0';
j++;
k = 0;
}
}
str4[j][k++] = '\0';
count2 = j > 0 ? j + 1 : j;
for (i = 0; i < count1; i++)
{
for (j = 0; j < count2; j++)
{
if (str3[i][k] == str4[j][k])
{
if (str3[i][k + 1] == str4[j][k + 1] && str3[i][k + 2] == str4[j][k + 2] == '\0')
{
a = i;
b = k;
while (str3[a][b] != '\0')
{
output = (char **)malloc(SIZE*sizeof(char));
output[m][n] = str3[a][b];
n++;
b++;
}
output[m][n] = '\0';
}
else if (str3[i][k + 1] == str4[j][k + 1] && str3[i][k + 2] == str4[j][k + 2])
{
a = i;
b = k;
while (str3[a][b] != '\0')
{
output = (char **)malloc(SIZE*sizeof(char));
output[m][n] = str3[a][b];
n++;
b++;
}
output[m][n] = '\0';
m++;
}
}
}
}
return output;
}
I am debugging this code in visual studios and the test is failed.Its showing this " message: Exception code: C0000005" .It means error related to memory space allocation.So where did i go wrong?
You have the statement
output = (char **)malloc(SIZE*sizeof(char));
at two lines of your program.
You have to modify this statement in order allocate memory for the double pointer output of type char**, but you also need to allocate memory for every element of output like this :
int i;
output = (char **)malloc(SIZE*sizeof(char*));
for (i = 0; i < SIZE; i++)
output[i] = (char *)malloc(x*sizeof(char));
where x is the desired size.
Also check for NULL pointer return, for instance
if (output[i] == NULL)
....
I have this code:
FILE *fr,*fr2,*fr3;
fr = fopen("med.txt","r");
fr2 = fopen("moje.txt","w");
fr3 = fopen("zaloha.txt","rw");
int pRadku, nc, inword, pMezery;
int pSlov = 0;
inword = 0;
pRadku = 1;
inword = 0;
int radky = 20;
int sloupce = 50;
nc = pMezery = 0;
int pocitadlo = 0;
int pocitadlo2 = 0;
int i,j;
char c;
int tex = 255;
char text;
for(i= 0; i<tex ;i++){
text[i]='\0';
}
char **pole;
int pocet = 1000;
char *p_pom1, *p_pom2, **p_nove;
pole = (char **)malloc(pocet * sizeof(char));
for(i=0; i<pocet; i++){
pole[i] = (char*)malloc(tex * sizeof(char));
}
while(( c=fgetc(fr)) != EOF){
++nc;
if(c == '\n'){
++pRadku;
}
if(c ==' '){
pMezery++;
}
if(c == ' ' || c == '\n' || c == '\t'){
inword = 0;
}else if(inword == 0){
inword = 1;
++pSlov;
}
if(pocitadlo >= (pocet-1)){
int pomPocet = pocet;
pocet+=1000;
pole = (char **)realloc(pole, pocet * sizeof(char));
}
if((c != ' ')){
if(c != '\0'){
if(c != '\n'){
if(c != '\t'){
if(c != '.'){
if(c != ','){
text[pocitadlo2]=c;
pocitadlo2++;
}
}
}
}
}
}
if((c == ' ')){
text[pocitadlo2] = '\0';
for(i=0;i<tex;i++){
pole[pocitadlo][i] = text[i];
}
for(i=0;i<tex;i++){
text[i]='\0';
}
pocitadlo2=0;
pocitadlo++;
}else if(c == '\0'){
text[pocitadlo2] = '\0';
for(i=0;i<tex;i++){
pole[pocitadlo][i] = text[i];
}
for(i=0;i<tex;i++){
text[i]='\0';
}
pocitadlo2=0;
pocitadlo++;
}else if(c == '\n'){
text[pocitadlo2] = '\0';
for(i=0;i<tex;i++){
pole[pocitadlo][i] = text[i];
}
for(i=0;i<tex;i++){
text[i]='\0';
}
pocitadlo2=0;
pocitadlo++;
}else if(c == '.'){
text[pocitadlo2] = '\0';
for(i=0;i<tex;i++){
pole[pocitadlo][i] = text[i];
}
for(i=0;i<tex;i++){
text[i]='\0';
}
pocitadlo2=0;
pocitadlo++;
}else if(c == ','){
text[pocitadlo2] = '\0';
for(i=0;i<tex;i++){
pole[pocitadlo][i] = text[i];
}
for(i=0;i<tex;i++){
text[i]='\0';
}
pocitadlo2=0;
pocitadlo++;
}
}
and my question is do I expand my 2 dimensional array properly? Or should do it some different way?
This program read 300 000 words from a file and saving them in to an array.
thx for your time.
EDIT**
int row = 5;
int column = 5;
int countr = 0;
int countr2 = 0;
int c;
int **array;
array = (int **)malloc(size * sizeof(int*));
for(i=0; i<row; i++){
pole[i] = (int*)malloc(column * sizeof(int*));
}
while(read letters form file (c=fgetc()) != EOF{
if(coutr>=(size-1)){
row+=10;
array = (int **)realloc(array, row * sizeof(int*));
}
array[countr][countr2] = c;
countr2++;
if(c == '\0' || c == ' '){
countr2=0;
countr++;
}
}
This code is so broken as to be impossible to diagnose what's wrong. As an example,
int tex = 255;
char texttex
for(i= 0; tex ;i++){
text[i]='\0';
}
is missing a semicolon after char texttex and is an infinite loop since tex is always 255. Please provide a complete minimal compilable code. If you expect others to spend time for you, you should start by spending some of your time for us. Thank you.
Wrong size is passed to malloc function: sizeof(char) that should be sizeof(char*):
pole = (char **)malloc(pocet * sizeof(*char));
sizeof(char) != sizeof(char*) and also don't use type cast for malloc().
And similar error I can see in your code in realloc :
error at: pole = (char **)realloc(pole, pocet * sizeof(char));
also a syntax error, ; is missing :
char texttex