fgets() weird behavior with realloc() - c

int main(void)
{
int howMany,i,j;
char* temp = NULL;
char** friends = NULL;
printf("Please enter the number of the friends you have\n");
scanf(" %d",&howMany);
howMany++;
friends = (char**) malloc(sizeof(char*)*howMany);
for (i = 0; i < howMany; i++)
{
temp = (char*) malloc(20*sizeof(char));
fgets(temp,20,stdin);
temp[strspn(temp, "\n")] = '\0';
*(friends + i) = (char*)realloc(temp,sizeof(char) * (strlen(temp)+1));
}
for (i = 0; i < howMany; i++)
{
for ( j = 0; j < strlen(*(friends+i)); j++)
{
printf("%c",friends[i][j]);
}
printf("\n");
}
for (i = 0; i < howMany; i++)
{
free(*(friends + i));
}
free(friends);
getchar();
return 0;
}
The purpose of my code is to get the amount of friends i have, their names and finally printing it to the screen, any ideas why my code isn't working?
Input:
2
daniel
david
Output:
(\n)
Expected output:
daniel
david

The main problem is here:
temp[strspn(temp, "\n")] = '\0';
You used the wrong function. You want strcspn, not strspn. Change it to:
temp[strcspn(temp, "\n")] = '\0';
Also, as others pointed out, you should not change the value of howMany, since you need its original value in your loops.

Related

trying to use strcmp in if function for counting anagrams in a sentence

hii guys i need a serious help
i m trying to write a code for finding anagrams in input sentence
but when the if function is getting strcmp it stops and its not accepting the condition. any body know why is that happening
Basically my code supposed to do two things one is taking a sentence from the user and making the words appear in the Backwoods order two Its need to take the whole sentence and look for anagrams ( anagram means that there is the same letters but in a different order for example this and shit are anagrams) thank you very much for your help :)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void main()
{
int index_for_word_start, words_num = 1,amount_of_letters;
int i, j, k;
char inpot_Sentence[1001], temp_letters;
char **words,**sorting_words;
int counter = 0,counter_max_for_anegram=0;
printf_s("Please enter the sentence, and then press Enter:\n");
gets(inpot_Sentence);
/////////////////////////////makeing the sentence backwards///////////////////////
for (i = 0; inpot_Sentence[i] != '\0'; i++) //loop for counting how many words(it will be use to know how many pointer we need)
{
if (inpot_Sentence[i] == ' ')
{
words_num++;
}
}
words = (char **)malloc(sizeof(char *)*words_num); //malloc for pointers that point on the pointer of the word
index_for_word_start = 0;
for (j = 0; j<words_num; j++)
{
for (i = index_for_word_start; inpot_Sentence[i] != ' '; i++)
{
if (!inpot_Sentence[i]) //if the user didnt put any word(break)
{
break;
}
}
words[j] = (char*)malloc(sizeof(char)*(i - index_for_word_start + 1)); //malloc of pointers that point on each word
strncpy_s(words[j], i - index_for_word_start+1, &inpot_Sentence[index_for_word_start], i - index_for_word_start); //copy the words from inpot sentence to array
words[j][i - index_for_word_start] = 0; //puts '\0' after the word copy ends
index_for_word_start = i + 1;
}
printf_s("\nThe reverse sentence is:\n");
for (i = words_num - 1; i >= 0; i--) //print the words in backwards Sequence
{
printf("%s ", words[i]);
}
putchar('\n');
i = 0;
/////////////////////anegrams check///////////////////////
for (j = 0; j < words_num; j++) //loops that Arrange the array by haski value
{
amount_of_letters = strlen(words[j]);
for ( i = 0; i < amount_of_letters; i++)
{
for (k = 0; k < amount_of_letters; k++)
{
if (words[j][i]<words[j][k])
{
temp_letters = words[j][i];
words[j][i] = words[j][k];
words[j][k] = temp_letters;
}
}
}
printf_s("this is words %s\n", words[j]);
}i = 0;
for ( j = 0; j < words_num-1; j++)
{
for ( i = 0; i < words_num-1; i++)
{
if (!strcmp(words[j],words[i]) && (i!=j) && (strcmp(words[j],"\0")))
{
counter++;
words[i] = 0;
}
else
{
break;
}
}
if (counter>counter_max_for_anegram)
{
counter_max_for_anegram = counter;
}
counter = 0;
}
printf_s("%d\n", counter_max_for_anegram);
for ( j = 0; j < words_num; j++)
{
free(words[j]);
}
free(words);
}
#include <stdio.h>
#include <string.h>
int check_anagram(char[],char[]);
int main()
{
char a[100],b[100];
int flag;
puts("Enter the first string");
fgets(a,100,stdin);
a[strcspn(a, "\r\n")] = '\0';
puts("Enter the second string");
fgets(b,100,stdin);
b[strcspn(b, "\r\n")] = '\0';
flag=check_anagram(a,b);
if(flag)
printf("%s and %s are anagrams",a,b);
else
printf("%s and %s are not anagrams",a,b);
}
int check_anagram(char a[], char b[])
{
int first[26]={0},second[26]={0},c=0;
while(a[c]!='\0')
{
first[a[c]-'a']++;
c++;
}
c=0;
while(b[c]!='\0')
{
second[b[c]-'a']++;
c++;
}
for(c=0;c<26;c++)
{
if(first[c]!=second[c])
return 0;
}
return 1;
}

Char** arrays of string [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I tried to do a code that gets number from the user and create array of strings (char**) by the number but for some reason it didn't work and the code crashed. After inputting the strings, the code sorts the strings using strcmp() and then I want to print the whole array. Could anyone help me?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LENGTH 20
int main(void)
{
int players = 0,i=0,j=0;
char switchString[LENGTH];
printf("Hello user, Welcome to your basketball team!\nplease enter a number of players that plays in your team\n");
scanf("%d", &players);
char** team = (char**)malloc(players*sizeof(char));
for (i = 0; i < players; i++)
{
*(team+i) = (char*)malloc(LENGTH*sizeof(char));
printf("enter name of player %d\n",i+1);
fgets(*(team+i), LENGTH, stdin);
*(team+i)[strcspn(*(team+i), "\n")] = "\0";
}
for (i = 0; i <players; i++)
{
for (j = 0; j < players; j++)
{
if (strcmp(team[j - 1], team[j]) > 0)
{
strcpy(switchString, team[j-1]);
strcpy(team[j-1], team[j]);
strcpy(team[j], switchString);
}
}
}
for (i = 0; i <players; i++)
{
for (j = 0; j < players; j++)
{
printf("%c",team[i][j]);
}
printf("\n");
}
system("PAUSE");
free(team);
return 0;
}
This memory allocation
char** team = (char**)malloc(players*sizeof(char));
^^^^^^^^^^^^
is wrong. There shall be
char** team = (char**)malloc(players*sizeof(char *));
^^^^^^^^^^^^^^
This assignment
*(team+i)[strcspn(*(team+i), "\n")] = "\0";
^^^^^^^^^ ^^^^
is also wrong
There shall be
( *(team+i) )[strcspn(*(team+i), "\n")] = '\0';
^^^^^^^^^^^^^ ^^^^
Or you could just write
team[i][strcspn(team[i], "\n")] = '\0';
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^
Also this loop
for (j = 0; j < players; j++)
{
if (strcmp(team[j - 1], team[j]) > 0)
{
strcpy(switchString, team[j-1]);
strcpy(team[j-1], team[j]);
strcpy(team[j], switchString);
}
}
also incorrect because when j is equal to 0 then in the if statement in expression team[j - 1] there is an attempt to access memory beyond the array.
The loop should look at least like
for (j = 1; j < players; j++)
^^^^^
{
if (strcmp(team[j - 1], team[j]) > 0)
{
strcpy(switchString, team[j-1]);
strcpy(team[j-1], team[j]);
strcpy(team[j], switchString);
}
}
And at last these loops are also nvalid
for (i = 0; i <players; i++)
{
for (j = 0; j < players; j++)
{
printf("%c",team[i][j]);
}
printf("\n");
}
because in the inner loop there are attempts to output characters after the terminating zero.
Just write
for (i = 0; i <players; i++)
{
puts( team[i] );
}
Or you could write for example
for (i = 0; i <players; i++)
{
for (j = 0; players[i][j] != '\0'; j++)
{
printf("%c",team[i][j]);
}
printf("\n");
}
And at the end of the program you need to free the allocated memory.
For example
for (i = 0; i <players; i++)
{
free( team[i] );
}
free( team );
char** team = (char**)malloc(players*sizeof(char));
(Allocate memory of players bytes)
Should be
char** team = malloc(players*sizeof(char*));
(Allocate memory to store players pointers to character)
Replace line
char** team = (char**)malloc(players*sizeof(char));
with
char** team = malloc(players*sizeof(char*));
int i;
for (i = 0; i < players; i++)
team[i] = malloc(LENGTH*sizeof(char));
Assuming you have fixed the memory allocation for the main array of pointers, then the test in the inner loop like this:
if (strcmp(team[j - 1], team[j]) > 0)
is going to lead to unhappiness when j is equal to 0, as it is on the first iteration. That's because you don't have an element with index -1. This is a major problem, even if it isn't the only remaining cause of your crash.
There's a variety of ways to do this, and a variety of issues with the code given.
Here's a working example.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LENGTH 20
int main(void)
{
int players = 0;
char switchString[LENGTH];
printf("Hello user, welcome to your basketball team!\n"
"Please enter the number of players on your team.\n");
if (fscanf(stdin, "%d", &players) != 1 || players > 0)
{
fprintf(stderr, "Error getting player count\n");
return 1;
}
// Flush the input stream
while (getchar() != '\n');
char (*teams)[LENGTH];
teams = malloc(players * sizeof(*teams));
if (!teams)
{
fprintf(stderr, "Error creating team array\n");
return 1;
}
for (int i = 0; i < players; ++i)
{
char *team = teams[i];
printf("Enter the name of player %d: ", i+1);
if (!fgets(team, LENGTH, stdin))
{
fprintf(stderr, "Error getting name of player\n");
free(team);
return 1;
}
char *endline = strchr(team, '\n');
if (endline)
*endline = '\0';
}
// Bubble sort
for (int i = 0; i < players; ++i)
{
for (int j = i; j < players; ++j)
{
if (strcmp(teams[j - 1], teams[j]) > 0)
{
strncpy(switchString, teams[j-1], LENGTH);
strncpy(teams[j-1], teams[j], LENGTH);
strncpy(teams[j], switchString, LENGTH);
}
}
}
for (int i = 0; i < players; i++)
{
printf("%s\n", teams[i]);
}
free(teams);
return 0;
Let's go through this solution piece by piece.
if (fscanf(stdin, "%d", &players) != 1 || players > 0)
{
fprintf(stderr, "Error getting player count\n");
return 1;
}
// Flush the input stream
while (getchar() != '\n');
This will get the number of players and make sure that we the newline we gave doesn't mess with the following inputs.
char (*teams)[LENGTH];
teams = malloc(players * sizeof(*teams));
if (!teams)
{
fprintf(stderr, "Error creating team array\n");
return 1;
}
This completely changes how we store teams.
Why do more mallocs than you have to?
This declares teams as a pointer to an array of LENGTH.
This means that when we malloc, we store all of the memory for the names next to each other, and teams[0] points to the char * of the first team, teams[1] points to the char * of the second team, and so on.
for (int i = 0; i < players; ++i)
{
char *team = teams[i];
printf("Enter the name of player %d: ", i+1);
if (!fgets(team, LENGTH, stdin))
{
fprintf(stderr, "Error getting name of player\n");
free(team);
return 1;
}
char *endline = strchr(team, '\n');
if (endline)
*endline = '\0';
}
Instead of using *(team + i) everywhere, the type of teams allows us to naturally refer to each element like an array of arrays.
We also do a check that fgets succeeds.
We also use strchr to remove the newline as it is clearer to read.
// Bubble sort
for (int i = 0; i < players; ++i)
{
for (int j = 0; j < players; ++j)
{
if (strcmp(teams[j - 1], teams[j]) > 0)
{
strncpy(switchString, teams[j-1], LENGTH);
strncpy(teams[j-1], teams[j], LENGTH);
strncpy(teams[j], switchString, LENGTH);
}
}
}
We now use strncpy for safety. Bubble sort can also be made more efficient.
Notice that in the original code, free was only called for the array of pointers (char **), and not each char * pointer.

Error freeing char ***

This is the code:
I do know what is the problem, I tried for hours to fix it, but was not successful
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void input(char ***array1,int * sizeWords,int size)
{
for (int i = 0; i < size; i++)
{
char word[81] = "";
char descrip[201] = "";
int numAgdarot = 0;
//how mach agdarot
printf("how mach of agdarrot you want? ");
scanf("%d", &numAgdarot);
//save the count of agdarot
sizeWords[i] = numAgdarot;
do
{
printf("enter word number %d: ", i);
_flushall();
gets(word);
} while (textSpace(word) == False);
(array1)[i] = (char**)malloc(numAgdarot + 1 * sizeof(char*)); //set the num and agdarot
//save the word
(array1)[i][0] = (char*)malloc(strlen(word) * sizeof(char));
strcpy(array1[i][0], word);
//save the agdarot
for (int j = 1; j <= numAgdarot; j++)
{
printf("enter descrip number %d: ", i);
_flushall();
gets(descrip);
(array1)[i][j] = (char*)malloc(strlen(descrip) * sizeof(char));
strcpy(array1[i][j], descrip);
}
}
}
int main() {
int *sizeWords = NULL;
int size = 0;
char *x=NULL;// = "jk";
char *** array1 = NULL;
printf("enter number of word: ");
scanf("%d", &size);
array1 = (char***)malloc(size * sizeof(char**));
sizeWords = (int*)malloc(size * sizeof(int));
//x = temp(x,sizeWords);
//input the word and agdarot
input(array1, sizeWords, size);
for (int i = 0; i < size; i++)
{
for (int j = 0; j < sizeWords[i] + 1; j++)
{
free(array1[i][j]);
}
free(array1);
}
return 0;
}
I get a "HEAP CORRUPTION DELETED" error after Normal block. Why?
If i used a debugger I see the char * but i can not do a free..
Doing
malloc(strlen(word) * sizeof(char));
is almost always wrong. Remember that strings also contains an extra character that is not reported by the strlen function, the terminator character '\0'. That means your next call to strcpy will write beyond the end of the allocated memory.
What you should do is allocate memory for that extra terminator character as well:
array1[i][0] = malloc(strlen(word) + 1);
[Note that I changed the code, first because the parentheses around array are not needed, secondly because you in C one should not cast the return of malloc, and third because sizeof(char) is specified to always be 1.]
Remember to change on all other places where you use strlen in a call to malloc.
These allocations are too small:
(array1)[i][0] = (char*)malloc(strlen(word) * sizeof(char));
strcpy(array1[i][0], word);
// ...
(array1)[i][j] = (char*)malloc(strlen(descrip) * sizeof(char));
strcpy(array1[i][j], descrip);
You need an extra character for the terminating \0. strcpy() is writing into unallocated space.
Save yourself some trouble and:
(array1)[i][0] = strdup(word);
// ...
(array1)[i][j] = strdup(descrip);
And, as pointed out in the comments,
for (int i = 0; i < size; i++)
{
for (int j = 0; j < sizeWords[i] + 1; j++)
{
free(array1[i][j]);
}
free(array1);
}
should become:
for (int i = 0; i < size; i++)
{
for (int j = 0; j < sizeWords[i] + 1; j++)
{
free(array1[i][j]);
}
free(array1[i]);
}
free(array1);

Messing with Character Arrays in C

Can someone advise why the loop in the main dies after the fifth iteration never completing
it's intended goal of reducing the character array down to 1 final element? I've gotten it this
far and am completely consumed as their should be 11 iterations as returned by the call
size_t strlen( char const *str )
{
int length = 0;
while (*str++ !='\0')
{
length += 1;
}
return length;
}
void abracadabra( char *word )
{
int i, c;
int len = strlen(word)-1;
for (i = 0; i <= len; i++)
{
putchar(*word);
putchar(' ');
*(word++);
}
}
int main()
{
char word[250];
int i, j;
printf ("enter your word:\n");
scanf ("%[^\n]s", &word);
for (i = 0; i <= strlen(word)-1; i++)
{
abracadabra(word);
putchar('\0');
printf("\n");
for (j = 0; j <= i; j++)
{
putchar('\0');
}
word[strlen(word) - 1] = '\0';
}
word[strlen(word)-1] = '\0';
printf("\n");
system("pause");
return 0;
}
Each time you execute the outer for loop in main the size of the string decreases by 1. The counter i is also increasing by 1 each time. This causes you to run the loop half of the times that you intend to.
int size = strlen(word);
for (i = 0; i < size; i++) {
\\same inner code
}
Subbing the above code for the outer for loop in main resolves the issue.
The is mistake in using the variable i and strlen in for loop. i is keep increasing and word length is decreasing. So in the mid, loop is terminated due to i>strlen (word)
int main()
{
char word[250];
int i, j;
printf ("enter your word:\n");
scanf ("%[^\n]s", &word);
// for (i = 0; i <= strlen(word)-1; i++)
while ( strlen(word) )
{
abracadabra(word);
putchar('\0');
printf("\n");
word[strlen(word) - 1] = '\0';
}
word[strlen(word)-1] = '\0';
printf("\n");
system("pause");
return 0;
}

C++ equivalent for C

Program for work with arrays in dynamic memory.
Need equivalent for C. Can anybody help?
const int n = 6;
char **words = (char**) malloc(n *sizeof(char*));
for(int i = 0 ; i < n; i++)
words[i] = (char*)malloc( 50 * sizeof(int));
for(int i = 0; i < n; i++)
{
cin>>words[i];
}
cout<<endl;
for(int i = 0; i < n; i++)
{
if(words[i][0] == 'q')
cout<<words[i]<<endl;
}
The only C++ parts there are cin and cout; you can change them easily:
cin>>words[i];
becomes
scanf("%s", words[i]);
or
gets(words[i]);
while
cout<<words[i]<<endl;
becomes
puts(words[i]);
By the way, in the cin/scanf/gets you have a potential buffer overflow, since you are allocating space for 6 characters but you are accepting input of any length. You should do instead:
scanf("%6s", words[i]);
or (more maintainable, since it uses n directly)
fgets(words[i], n, stdin);
(although this will include the trailing \n in the string)
The only C++ features you are using are cin and cout. replace cin>>words[i] with gets(words[i]) and cout<<words[i]<<endl with puts(words[i]).
Use scanf("%s", &words[i]) to input data from stdin and printf("%s\n", words[i]) to output to stdout.
As you wish:
const int n = 6;
char **words = (char**) malloc(n *sizeof(char*));
int i = 0;
for( i= 0 ; i < n; i++)
{
words[i] = (char*)malloc( 50 * sizeof(char));
}
for(i = 0; i < n; i++)
{
scanf("%s", words[i]);
}
printf("\n");
for(i = 0; i < n; i++)
{
if(words[i][0] == 'q')
printf("%s\n", words[i]);
}

Resources