How to expand 2 dimensional dynamic array in C? - c

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

Related

Splitting word by specific char work with string but don't work with argv[1]

I have an issue with my program.
My program split word using \t \n or space and put the word into a array of string.
when i call my function like this its works perfectly :
ft_print_words_tables(ft_split_whitespaces("Hello Everyone this is a test"));
but when i try to send the first command line param like this :
ft_print_words_tables(ft_split_whitespaces(argv[1]));
i'm getting the following error :
./a.out "test test tast"
a.out(97132,0x7fff706ff000) malloc: * error for object 0x7f9e09403228: incorrect checksum for freed object - object was probably modified after being freed.
* set a breakpoint in malloc_error_break to debug
[1] 97132 abort ./a.out "test test tast"
here is the code :
#include <stdlib.h>
// This func return the word nbr
int ft_compte_mot(char *str) {
int i = 0;
int j = 0;
while(str[i] == ' ' || str[i] == '\t' || str[i] == '\n') {
i++;
while (str[i] != '\0') {
if ((str[i] == ' ' || str[i] == '\n' || str[i] == '\t') &&
(str[i + 1] >= '!' && str[i + 1] <= 'z')) {
j++;
}
i++;
}
return (j + 1);
}
// this func count the word lenght and put them in an int array
int *ft_compte_taille_mot(int *taillemot, char *str) {
int i = 0;
int j = 0;
int k = 0;
while (str[i] != '\0') {
j = 0;
while ((str[i] == ' ' || str[i] == '\n' || str[i] == '\t')
&& str[i] != '\0')
i++;
while (str[i] != ' ' && str[i] != '\n' && str[i] != '\t'
&& str[i] != '\0') {
j++;
i++;
}
taillemot[k] = j;
i++;
k++;
}
return (taillemot);
}
void ft_copy_word(int *taillemot, int nbmot, char **tab, char *str) {
int i = 0;
int j = 0;
int k = 0;
while (str[i] != '\0' && k < nbmot) {
j = 0;
while ((str[i] == ' ' || str[i] == '\n' || str[i] == '\t')
&& str[i] != '\0')
i++;
while (j < taillemot[k]) {
tab[k][j] = str[i];
j++;
i++;
}
//tab[k][j] = '\0';
i++;
k++;
}
tab[nbmot] = 0;
}
char **ft_split_whitespaces(char *str) {
int nbmot = ft_compte_mot(str);
int *taillemot;
int i = 0;
char **string;
if ((taillemot = (int*)malloc(sizeof(int) * nbmot)) == NULL)
return (NULL);
ft_compte_taille_mot(taillemot, str);
if ((string = (char **)malloc(sizeof(char *) * (nbmot + 1))) == NULL)
return (NULL);
while (i < nbmot) {
if ((string[i] = (char *)malloc(sizeof(char) * taillemot[i] + 1))
== NULL)
return (NULL);
i++;
}
ft_copy_word(taillemot, nbmot, string, str);
return (string);
}
void ft_putchar(char c) {
write(1, &c, 1);
}
void ft_putstr(char *str) {
int i = 0;
while (str[i] != '\0') {
ft_putchar(str[i]);
i++;
}
}
void ft_print_words_tables(char **tab) {
int i;
i = 0;
while (tab[i] != 0) {
ft_putstr(tab[i]);
ft_putchar('\n');
i++;
}
ft_putchar('\n');
}
EDIT : Here is the main EDIT 2 : I also tested with argv[1]
char **ft_split_whitespaces(char *str);
void ft_print_words_tables(char **tab);
void ft_putchar(char c)
{
write(1, &c, 1);
}
int main(int argc, char **argv)
{
ft_print_words_tables(ft_split_whitespaces(argv[1]));
return (0);
}
FYI i'm in school and we have a particular norm, we can't use for loop or a bunch of libc function.
I'm really stuck here and i really don't understand why it's work with " " but not with **argv
thx by advance for your help
I found the solution :
char *str;
str = argv[1];
str[strlen(str) + 1] = '\0';
ft_print_words_tables(ft_split_whitespaces(str));
return (0);
thanks for the help

splitting a string by white spaces

Before reading this question please note that my question pertains to a school assignment. For this assignment the only function we are allowed to use is malloc(). Everything else must be done without the use of other libraries.
I'm calling a function ft_split_whitespaces. This function takes a string as input and "splits" it into words. Words are separated spaces, tabs and line breaks.
#include <stdio.h>
char **ft_split_whitespaces(char *str);
int main(void)
{
char *str = "what is";
char **test = ft_split_whitespaces(str);
}
With respect to the example above the result at each index should be
test[0] = "what"
test[1] = "is"
test[2] = NULL
However, I am only able to print the results of test[0]. All other indices do not get printed to display. Heres an example of some code that I assume should print the results of my function.
int i = 0;
while(test[i] != NULL)
{
printf("%s", test[i]);
i++;
}
When this portion of code is ran, only test[0] is printed to the output. I've been sitting here trying to debug my code for hours. If anyone has some spare time and doesn't mind looking over my code, I'd appreciate it tremendously. I have a feeling it may be an issue with how I'm using malloc, but I still cant figure it out.
#include <stdlib.h>
#include <stdio.h>
int count_whitespaces(char *str)
{
int space_count;
int i;
space_count = 0;
i = 0;
while(str[i] != '\0')
{
if(str[i] == ' ' || str[i] == 9 || str[i] == '\n')
{
if(str[i+1] != ' ' && str[i+1] != 9 && str[i+1] != '\n')
space_count++;
}
i++;
}
return (space_count);
}
int check_whitespace(char c)
{
if (c == ' ' || c == 9 || c == '\n' || c == '\0')
{
return (1);
}
else
return(0);
}
int count_characters(char *str, int i)
{
int char_count;
char_count = 0;
while(str[i])
{
if(str[i+1] != ' ' && str[i+1] != 9 && str[i+1] != '\n')
char_count++;
else
break;
i++;
}
return (char_count);
}
char **ft_split_whitespaces(char *str)
{
int i;
int j;
int k;
char **word;
int space;
i = 0;
j = 0;
k = 0;
word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
while(str[i] != '\0')
{
if (check_whitespace(str[i]) == 1)
i++;
else
{
if((word[j] = malloc(sizeof(char) * (count_characters(str, i) + 1))) == NULL)
return (NULL);
while (check_whitespace(str[i]) == 0)
{
word[j][k] = str[i];
i++;
k++;
}
j++;
}
}
j++;
word[j] = NULL;
j = 0
return word;
}
You forgot to reset k. The outer while loop in ft_split_whitespaces should look like that
while (str[i] != '\0') {
if (check_whitespace(str[i]) == 1){
i++;
}
else {
if ((word[j] =
malloc(sizeof(char) * (count_characters(str, i) + 1))) == NULL){
return (NULL);
}
while (check_whitespace(str[i]) == 0) {
word[j][k] = str[i];
i++;
k++;
}
word[j][k] = '\0';
j++;
k = 0; // reset k
}
}
So I actually figured out what was going wrong with my code as I finished typing this question (thanks stack overflow!). I decided to post it anyways, because I thought it might be a good learning experience for coding newbies such as myself.
This is where my issue was occurring.
word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
while(str[i] != '\0')
{
if (check_whitespace(str[i]) == 1)
i++;
else
{
if((word[j] = malloc(sizeof(char) * (count_characters(str, i) + 1))) == NULL)
return (NULL);
while (check_whitespace(str[i]) == 0)
{
word[j][k] = str[i];
i++;
k++;
}
j++;
}
}
I malloc'd my char **word outside of the while loop using the following code
word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
And then within the actual while loop I malloc'd it again using
word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
Using malloc multiple times on the same variable was causing all sorts of weird issues. So within the while loop I ended up using a new variable I declared as char *words. Here is that portion of the while loop with the correct code.
word = (char**)malloc(sizeof(char*)*(count_whitespaces(str) + 2));
while(str[i] != '\0')
{
if (check_whitespace(str[i]) == 1)
i++;
else
{
words = malloc(sizeof(char) * (count_characters(str, i) + 1));
k = 0;
while (check_whitespace(str[i]) == 0)
{
words[k] = str[i];
i++;
k++;
}
words[k] = '\0';
word[j] = words;
j++;
}
}

C - Can't add to or call specific array?

My program takes two parameters eg "./a abc xyz" where all a's in a text file are replaced with x's and b's with y's and so on. When given a range, eg. A-C, it reads it as ABC.
The issue I am having is that when I add chars to a certain array(alphaRange2) I get a segmentation fault when I run it. I use the same code for array alphaRange1, which does accept the chars as shown when I print alphaRange1 in a for loop. When I try to print alphaRange2, no values are printed.
Here's my code:
int translate(char set1[], char set2[]) {
int c;
char ch;
char ch2;
int dash1 = 0;
int dash2 = 0;
int previous = -1;
int next;
char alphaRange1[MAXSIZE];
char alphaRange2[MAXSIZE];
size_t i;
int j = 0;
int k;
int l;
for (i=0; i <= strlen(set1); i++) {
if (set1[i] == '-') {
for (ch = set1[i-1]; ch <= set1[i+1]; ch++) {
alphaRange1[k] = ch;
k++;
}
}
}
for (i=0; i <= strlen(set2); i++) {
if (set2[i] == '-') {
for (ch = set2[i-1]; ch <= set2[i+1]; ch++) {
alphaRange2[l] = ch;
l++;
}
}
}
/*for (i=0; alphaRange1[i] != '\0'; i++) {
printf("%c", alphaRange1[i]);
}*/
while ((c = getchar()) != EOF) {
if ((dash1 == 1) && (dash2 == 1)) {
for (i=0; alphaRange1[i] != '\0' || alphaRange2[i] != '\0'; i++) {
if (c == alphaRange1[i]) {
c = alphaRange2[i];
}
}
} else if ((dash1 == 0) && (dash2 == 0)) {
for (i=0; i <= strlen(set1) || i <= strlen(set2); i++) {
if (c == set1[i]) {
c = set2[i];
if ((c == set1[1]) && (set1[1] == set2[0])) {
c = set2[0];
break;
}
}
}
}
if (previous > -1) {
putchar(previous);
}
previous = c;
}
putchar('\n');
return 1;
}
int main(int argc, char *argv[]) {
int i, j, k;
char set1[MAXSIZE];
char set2[MAXSIZE];
char ch;
char alphaRange1[MAXSIZE];
for (i=0; i < argc; i++) {
for (j=0; argv[1][j] != '\0' || argv[2][j] != '\0'; j++) {
set1[i] = argv[1][i];
set2[i] = argv[2][i];
}
}
/*for (i=0; i <= strlen(set1); i++) {
if (set1[i] == '-') {
for (ch = set1[i-1]; ch <= set1[i+1]; ch++) {
alphaRange1[k] = ch;
k++;
}
}
}
for (i=0; alphaRange1[i] != '\0'; i++) {
printf("%c", alphaRange1[i]);
}*/
translate(set1, set2);
return 1;
}
The code runs if you take out anything including alphaRange2, and I've been testing it using commented out print loop, which works if you comment out the entire while loop. How do I make this work?
Thanks.

why getchar() doesn't get next value from input?

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

c freeing char pointer not working after first time

I am trying to free a char pointer wich was allocated by the function copyCharNumber. The first time the free call in the function works fine. The second time it doesn´t work any more and Visual Studio throws an error. I don`t get it why there is an error the second time. The second time calling free on the char pointer returned by the copyCharNumber anywhere in the code allways throws an error.
Code:
char* copyCharNumber(char *oldNumber, char *newDigit, int newLen){
char* newNumber = malloc(newLen * sizeof(char) +1);
if (oldNumber != NULL){
strcpy(newNumber, oldNumber);
free(oldNumber);
}
*(newNumber + (newLen - 1)) = *newDigit;
*(newNumber + newLen) = "\0";
return newNumber;
}
double* getNumbers(int max, int maxValue, int minValue, char* filenameRead){
double* numbers = malloc(max * sizeof(double));
FILE* fp = fopen(filenameRead, "r");
char ch = NULL;
int i = 0;
int numberLen = 0;
boolean isNegative = 0;
int hasPoint = 0;
for (; i < max && fp != NULL && ch != EOF; i++){
isNegative = 0;
numberLen = 0;
hasPoint = 0;
char* number = NULL;
if (ch == NULL)
ch = fgetc(fp);
if (ch == '-') isNegative = 1;
if (ch == '.' || ch == ',' && numberLen > 0) hasPoint++;
while (isdigit(ch)>0 || (isNegative && numberLen == 0) || (hasPoint == 1 && numberLen>0)){
numberLen++;
number = copyCharNumber(number, &ch, numberLen);
ch = fgetc(fp);
}
if (number != NULL){
double newNumber = strtod(number, NULL);
free(number);
if (newNumber <= maxValue && newNumber >= minValue){
if (isNegative) newNumber = -newNumber;
numbers[i] = newNumber;
}
}
else
ch = NULL;
}
return numbers;
}

Resources