resolving memory loss between two arrays in C - c

Good evening. I'm working on a program for class and I am hitting a brick wall when it comes to dealing with arrays using C.
--EDIT-- Full code has been posted.
#define _CRT_SECURE_NO_WARNINGS
#define STRMAX 20
#define MAX 100
#include<stdio.h>
int main()
{
int count = 0;
char strlist[STRMAX][MAX];
int start = 0, end = STRMAX;
for (start; start < end; start++) {
char string[MAX];
printf("Enter a string: ");
fgets(string, MAX - 1, stdin);
printf("\nThe string is: %s", string);
int size = strlen(string);
int result = strcmp(string, "stop\n");
if (result == 0) {
break;
}
strcpy(strlist[start], string);
count = count + 1;
}
char rev[STRMAX][MAX];
int temp = 0;
printf("count is: %d\n",count);
while (count != 0) {
strcpy(rev[temp], strlist[count]);
temp = temp + 1;
count = count - 1;
}
printf(rev);
return 0;
}
The last line, printf(rev); is throwing the warning: "using uninitialized memory 'rev'. "
I do not understand C, its the beginning of this course. However I am NOT looking for a "do my homework for me" answer, more of a "here is a better way to go about this" answer.
the output for the code is:
Enter a string: 1
The string is: 1
Enter a string: 2
The string is: 2
Enter a string: 3
The string is: 3
Enter a string: stop
The string is: stop
count is: 3
╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠3
the "count is: 3" is entirely for debugging. I really don't have a clue why my solution doesn't work. If there is any more information that is needed or anything else you would like to see feel free to ask and i'll update the post! thanks.
--EDIT--
STRMAX and MAX are both definitions set for the 2D array required for keeping an array of strings (20 and 50 respectively)

First of all, the line
strcpy(rev[temp], strlist[count]);
is wrong. Valid indexes for strlist are 0 to count-1, assuming that you only want to read valid strings. However, you are using the indexes 1 to count instead. Therefore, you should move the line
count = count - 1;
before that line.
Also, the line
printf(rev);
does not make sense.
If you want to print all strings in the array, then you should print every string individually, in a loop.
Since you are storing the number of valid strings in the variable temp, you must print that many strings.
for ( int i = 0; i < temp; i++ )
{
printf( "%s\n", rev[i] );
}
Also, you should #include <string.h>, because you are using strcpy and strlen.
Additionally, you probably should remove the trailing newline character from the input obtained from fgets. Otherwise, you will be printing that newline character, which will give you unwanted extra lines, forcing you to compensate by printing less newline characters explicitly. The existance of the newline character is also forcing you to add a newline character to the target string "stop":
int result = strcmp(string, "stop\n");
You will be able to remove that newline character from the target string if you also remove it from the input string.
After making these changes, your code should look like this:
#define _CRT_SECURE_NO_WARNINGS
#define STRMAX 20
#define MAX 100
#include <stdio.h>
#include <string.h>
int main()
{
int count = 0;
char strlist[STRMAX][MAX];
int start = 0, end = STRMAX;
for (; start < end; start++) {
char string[MAX];
printf("Enter a string: ");
fgets(string, MAX - 1, stdin);
//remove trailing newline character
string[strcspn(string,"\n")] = '\0';
printf("The string is: %s\n", string);
int result = strcmp(string, "stop");
if (result == 0) {
break;
}
strcpy(strlist[start], string);
count = count + 1;
}
char rev[STRMAX][MAX];
int temp = 0;
printf("count is: %d\n",count);
while (count != 0) {
count = count - 1;
strcpy(rev[temp], strlist[count]);
temp = temp + 1;
}
for ( int i = 0; i < temp; i++ )
{
printf( "%s\n", rev[i] );
}
return 0;
}
This program has the following output:
Enter a string: 1
The string is: 1
Enter a string: 2
The string is: 2
Enter a string: 3
The string is: 3
Enter a string: stop
The string is: stop
count is: 3
3
2
1

Related

Counting Characters and Strings n C

This is one of the assignments for my class and this is the objective of the assignment:
Write a program whose input is a character and a string, and whose output indicates the number of times the character appears in the string. The output should include the input character and use the plural form, n's, if the number of times the characters appears is not exactly 1. You may assume that the string does not contain spaces and will always contain less than 50 characters.
This is the code I have so far and I am new to C programming so I don't know how to declare Strings correctly just yet. So far I learned there are no strings in C like there is in Java and you have to do them as a character array:
#include <stdio.h>
#include <string.h>
int main(void) {
char userChar;
char userString[50];
int count = 0;
for (int i = 0; i < userChar; i++) {
if (userString[i] == userChar)
count++;
}
printf("%d", count);
if (count != 1)
printf("'s");
return 0;
}
For example, if I wanted to input n Monday and output 1 n
What would I need to change in my code to go from n Monday to 1 n
This is the only output I am getting, and it only has outputted one thing correctly:
0's
First, I hope this is not considered cheating :-)
Second, you need to define userChar and userString as arguments for main, and pass them in at run time. They are assigned nothing, so that is why you get
0's
Third, your for condition is wrong. You need this so it only iterates through the length of the string:
for (int i = 0; i < strlen(userString); i++)
Finally, You are not printing the value of userChar prior to the return
At first you need to input a string and a character. To count the number of occurrences of the character in the string you can use standard string function strchr.
The program can look something like the following
#include <stdio.h>
#include <string.h>
int main(void)
{
char userChar = ' ';
char userString[50] = "";
printf( "Enter a string without embedded spaces\nof the length less than %d: ", 50 );
scanf( "%49s", userString );
printf( "Enter a character to search in the string: " );
scanf( " %c", &userChar );
size_t n = 0;
for ( const char *p = userString; ( p = strchr( p, userChar ) ) != NULL; ++p )
{
++n;
}
printf( "%zu%s %c\n", n, n < 2 ? "" : "'s", userChar );
}
The expected output is not 0's, it should include the counted character: for example if the character is n and the string Monday, the output should be
1 n
and if the string is Eeny-meeny-miny-moe, the output would be
3 n's
Here is a modified version:
#include <stdio.h>
int main() {
char userChar;
char userString[50];
int i, count;
printf("Enter character: ");
scanf(" %c", &userChar);
printf("Enter string (single word): ");
// read a word with at most 49 characters
scanf(" %49s", userString);
count = 0;
for (i = 0; userString[i] != '\0'; i++) {
if (userString[i] == userChar)
count++;
}
printf("%d %c", count, userChar);
if (count != 1)
printf("'s");
printf("\n");
return 0;
}

How to find number of occurrences in array of chars in C?

I am trying to enter a word, and get how many times the letters were typed.
Say my input is "hello"
my output would be: h = 1, e = 1 l = 2 etc.
I am very close to getting it right, but I have a small issue with this code:
#include <stdio.h>
#include <string.h>
void find_frequency(char s[], int count[]) {
int c = 0;
while (s[c] != '\0') {
if (s[c] >= 'a' && s[c] <= 'z' )
count[s[c]-'a']++;
c++;
}
}
int main()
{
char string[100];
int c, count[26] = {0};
printf("Input a string\n");
gets(string);
find_frequency(string, count);
printf("Character Count\n");
for (c = 0 ; c < 26 ; c++)
if(count[c] > 0)
printf("%c : %d\n", c + 'a', count[c]);
return 0;
}
This code does half of the job, but not all.
It's output is in alphabetical order. How can i change it to give me an output of just the chararray that is input?
As Ry- suggested in this comment you could iterate back over the original string and use the chars as indices into your frequency table. Something like the following:
int len_string = strlen(string);
for (c=0; c<len_string; c++) {
char ch = string[c];
printf("%c: %d, ", ch, count[ch-'a']);
}
This won't completely match your expected output, since this code will output l: 2 twice, but that raises the question:
What is your expected output when you have a string like abba? a:2, b:2? a:1, b:2, a:1? a: 2, b:2, a:2? It's hard to help when you ask such an ambiguous question.
#include <stdio.h>
#include <string.h>
size_t ASCIIfreq[256];
void CountASCII(void *buff, size_t size)
{
unsigned char *charsptr = buff;
memset(ASCIIfreq, 0, sizeof(ASCIIfreq));
while(size--)
{
ASCIIfreq[*charsptr++]++;
}
}
void print(int printall)
{
for(size_t index = 0; index < 256; index++)
{
if(ASCIIfreq[index] || printall)
{
printf("The %03zu (0x%02zx) ASCII - '%c' has occured in the buffer %zu time%c\n",
index, index, (index > 32 && index < 127) ? (char)index : ' ',
ASCIIfreq[index], ASCIIfreq[index] == 1 ? ' ' : 's');
}
}
}
int main()
{
char teststring[] = "i am trying to enter a word, and get how many times the letters were typed. Say my input is \"hello\" my output would be: h = 1, e = 1 l = 2 etc.I am very close to getting it right, but i have a small issue with this code";
CountASCII(teststring, sizeof(teststring));
print(0);
return 0;
}
It's not clear what you mean by:
How can i change it to give me an output of just the chararray that is input?
Because that's exactly what you're doing in any case: Inputting a char array to the function; which is updated with numbers alphabetically; and later output as is.
So I'm guessing that you want to output the counts in the same order that each char was first encountered?
Solution
This will require a bit more work. You could keep a second array tracking the the order each character is encountered within find_frequency. But then that simple clean function starts doing too much.
So consider rather tweaking how you do the output:
void output_frequency(char s[], int count[]) {
int c = 0;
//loop s for the output
while (s[c] != '\0') {
if (s[c] >= 'a' && s[c] <= 'z' ) {
//found a character, report the count only if not reported before
if (count[s[c]-'a'] > 0) {
printf("%c : %d\n", s[c], count[s[c] - 'a']);
count[s[c]-'a'] = 0; //so you don't report this char again
}
}
c++;
}
}
If you are attempting to get an in-order count instead of a count in alphabetical order, you simply need to coordinate the indexes of your count array with the order of characters in your input buffer. To do that, simply loop over all characters in your input buffer and make a second pass counting the number of times the current character occurs. This will give you an in-order count of the number of times each character occurs, e.g.
#include <stdio.h>
#include <string.h>
#define COUNT 128
#define MAXC 1024
int main (void) {
char buf[MAXC] = ""; /* buffer to hold input */
int count[COUNT] = {0}; /* array holding inorder count */
fputs ("enter string: ", stdout); /* prompt for input */
if (!fgets (buf, MAXC, stdin)) { /* read line into buf & validate */
fputs ("error: EOF, no valid input.\n", stderr);
return 1;
}
/* loop over each character not '\n' */
for (int i = 0; buf[i] && buf[i] != '\n'; i++) {
char *p = buf; /* pointer to buf */
size_t off = 0; /* offset from start of buf */
while ((p = strchr (buf + off, buf[i]))) { /* find char buf[i] */
count[i]++; /* increment corresponding index in count */
off = p - buf + 1; /* offset is one past current char */
}
}
for (int i = 0; count[i]; i++) /* output inorder character count */
printf (i ? ", %c: %d" : "%c: %d", buf[i], count[i]);
putchar ('\n'); /* tidy up with new line */
return 0;
}
(note: strchr is used for convenience to simply find the next occurrence of the current character within the string and then off (offset) is used to start the search with the following character until no other matches in the string are found. You can simply use an additional loop over the characters in the buffer if you like.)
Example Use/Output
$ /bin/charcnt_inorder
enter string: hello
h: 1, e: 1, l: 2, l: 2, o: 1
However, this does recount each character and give the count again if the character is duplicated, (e.g. l: 2, l: 2 for each 'l'). Now it is unclear from:
"my output would be: h = 1, e = 1 l = 2 etc."
what you intended in that regard, but with just a little additional effort, you can use a separate index and a separate array to store the first instance of each character (in say a chars[] array) along with the count of each in your count[] array and preserve your inorder count while eliminating duplicate characters. The changes needed are shown below:
#include <stdio.h>
#include <string.h>
#define COUNT 128
#define MAXC 1024
int main (void) {
char buf[MAXC] = "",
chars[COUNT] = ""; /* array to hold inorder chars */
int count[COUNT] = {0};
size_t cdx = 0; /* add count index 'cdx' */
fputs ("enter string: ", stdout);
if (!fgets (buf, MAXC, stdin)) {
fputs ("error: EOF, no valid input.\n", stderr);
return 1;
}
for (int i = 0; buf[i] && buf[i] != '\n'; i++) {
char *p = buf;
size_t off = 0;
chars[cdx] = buf[i]; /* store in chars array */
if (i) { /* if past 1st char */
int n = i;
while (n--) /* simply check all before */
if (buf[n] == buf[i]) /* if matches current */
goto next; /* bail and get next char */
}
while ((p = strchr (buf + off, buf[i]))) {
count[cdx]++; /* increment count at index */
off = p - buf + 1;
}
cdx++; /* increment count index */
next:; /* goto label to jump to */
}
for (int i = 0; count[i]; i++)
printf (i ? ", %c: %d" : "%c: %d", chars[i], count[i]);
putchar ('\n');
return 0;
}
Example Use/Output
$ /bin/charcnt_inorder2
enter string: hello
h: 1, e: 1, l: 2, o: 1
or
$ ./bin/charcnt_inorder2
enter string: amarillo
a: 2, m: 1, r: 1, i: 1, l: 2, o: 1
Now your 'l' is only reported once with the correct count.
Note, in each example you should do additional validation to insure the entire input fit within your buffer, etc... The count (and chars) array were sized at 128 to cover the entire range of ASCII values. Don't skimp on buffer size. If you explicitly limit your input to UPPERcase or lowercase -- then you can limit your count size to 26, otherwise you need to consider the additional characters and punctuation that will be encountered. The same applies to your input buffer. If you anticipate you max input would be 500 chars, double it (generally to next available power of two, no real requirement for powers of two, but you are likely to see it that way).
Bottom line, I'd rather be 10,000 characters too long that one character too short... leading to Undefined Behavior.
Lastly, as mentioned in my comment never, never, never use gets. It is so insecure it has been removed from the C standard library in C11. Use fgets or POSIX getline instead.
Look things over and let me know if you have further questions.

Trying to check if a number is a palindrome through the use of strings [duplicate]

This question already has answers here:
How do I check if a number is a palindrome?
(53 answers)
Closed 5 years ago.
I am trying to check if an input number is a palindrome. I am doing it through strings rather than ints. So, I am taking in a string and reversing it into another string. However, when I use the string compare function it does not give me 0, stating that the strings are not the same. Even when I put in for example "1001", both the input and reverse strings displays 1001. I have figured it out with other methods but am trying to understand what is wrong with this one in specific.
#include <stdio.h>
#include <string.h>
int main(void)
{
char input[100];
char reverse[100];
int numLen = 0;
printf("Enter a number\n");
fgets(input, 100, stdin);
printf("The number is: %s\n", input);
numLen = strlen(input) - 1;
printf("Length of string is: %d\n", numLen);
for (int i = 0; i < numLen; i++)
{
reverse[i] = input[numLen - 1 - i];
if (i == numLen - 1)
{
reverse[i + 1] = '\0';
}
}
printf("The reverse number is: %s\n", reverse);
printf("The original number is: %s\n", input);
int result = strcmp(input, reverse);
printf("Result of strcmp gives us: %d\n", result);
if (strcmp(input, reverse) == 0)
{
printf("These numbers are palindromes\n");
}
else
{
printf("These numbers are not palindromes\n");
}
return 0;
}
The problem is you are not handling the strings properly. You should overwrite the '\n' with \0.
...
char input[100];
char reverse[100];
int numLen = 0;
printf("Enter a number\n");
fgets(input, 100, stdin);
printf("The number is: %s\n", input);
input[strcspn(input,"\n")]='\0'; // getting the length of the
// string without `\n`
// and overwriting with `\0`
numLen = strlen(input) ; // now you don't need to put the -1
printf("Length of string is: %d\n", numLen);
for (int i = 0; i < numLen; i++)
{
....
Apart from these two changes everything else remains the same. You were reversing it all right. And then you used strcmp right way. But the extra \n is removed in the code I have shown.
(still) Why it works?
Now to give you a better idea. You formed the reversed string alright. But the original string has \n within itself.
printf("The reverse number is: (%s)\n", reverse);
printf("The original number is: (%s)\n", input);
In the previous program you just do write these two lines. You will understand where you went wrong.
On giving input 1001Enter it gives this output.
The reverse number is: (1001)
The original number is: (1001
)
What is strcspn doing?
I have using strcspn function got the length without \n and overwriting it with \0.
0 1 2 3 4 5 --> indices
1 0 0 1 \n \0 --> strcspn(input,"\n") returns 4.
1 0 0 1 \0 \0 --> input[strcspn(input,"\n")]='\0'
You can do simply like this without the copying and everything.
Without extra memory - in place palindrome checking
bool checkPal(const char *s){
for(int i = 0, j= strlen(s)-1; i< strlen(s) && j>=0 ; i++)
if(s[i] != s[j])
return false;
return true;
}
int main(void)
{
char input[100];
char reverse[100];
printf("Enter a number\n");
if( fgets(input, 100, stdin) )
printf("The number is: %s\n", input);
input[strcspn(input,"\n")]='\0';
int numLen = strlen(input) ;
printf("Length of string is: %d \n", numLen);
printf("These numbers are %spalindromes\n", checkPal(input)?"not ":"");
return 0;
}
A more succinct way to write the checkPal() would be,
bool checkPal(const char *first){
const char *last = first + strlen(first);
while (first < last) {
if (*first++ != *--last) {
return false;
}
}
return true;
}
last points to the \0 character. Subtraction is necessary before we start doing comparison. To get a clear idea of what happens you have to know the precedence and few rules.
The first<last part is obvious. We are comparing till we reach a point where we first > last (For even length strings) or first = last (for odd length strings).
The if is a bit tricky. *first++ there are two operators involved. * (indirection) and ++(post increment).
And precedence of ++ is higher than de-reference *.
So *first++ will be - first is incremented. Then you might think that we are missing one character very first time but that's not the case. Value of a postfix expression is the value before we do first++. So now you have the first character.
Same way *--last will have the same effect except the value of the prefix expression is the value after the operation. So you are considering the last character.
If they matches we continue. first and last already contain the modified value. We repeat the same logic for rest of the characters in the smaller sub-string.
If a mismatch occurs then we return immediately. (Because it's not a palindrome).
Sorry, my bad. Try this:
#include <stdio.h>
#include <string.h>
// A function to check if a string str is palindrome
void isPalindrome(char str[])
{
// Start from leftmost and rightmost corners of str
int l = 0;
int h = strlen(str) - 1;
// Keep comparing characters while they are same
while (h > l)
{
if (str[l++] != str[h--])
{
printf("%s is Not Palindromen", str);
return;
}
}
printf("%s is palindromen", str);
}
// Driver program to test above function
int main()
{
isPalindrome("abba");
isPalindrome("abbccbba");
isPalindrome("geeks");
return 0;
}
Does this one work?
A variant, recursive version that has no more that the string as argument (or a copy of the original string)
int pal(char *s) {
int n = strlen(s);
if (n <= 1) return 1;
if (s[0] != s[n-1]) return 0;
s[n-1] = '\0';
return pal(++s);
}
return 0: not a palindrome, 1: is a palindrome
Note the string is altered, so you can call it this way if it's a problem (or if the string is created in a static area)
char *copy = malloc(strlen(string)+1); // string is original string
strcpy(copy, string);
int ispal = pal( copy );
printf("Is %s a palindrome\n", ispal ? "":"not");

printf not printing last character

I'm making a simple code for simulating Caesar's cypher and I'm having a weird bug where, although the output string fraseout[] is formed correctly and will print correctly at the very last print it gets it's last character trimmed. Why is this happening?
#include <stdio.h>
#include <string.h>
#include <math.h>
int main (void)
{
printf("Insira a frase:\n");
char frase [256];
scanf("%s", frase);
int size = (int)strlen(frase);
printf("Insira o tamanho da divergência: \n");
int diff = 0;
scanf("%i", &diff);
char fraseout [size];
int i = 0;
for (i = 0; i<=size-1; i++)
{
int val = (int)frase[i];
if (val + diff > 126)
{
val = 31+diff-(126-val);
}
else if (val +diff < 32)
{
val = 127 + diff+(val-32);
}
else
{
val +=diff;
}
fraseout [i] = (char)val;
}
printf("\"%s\" -> \"%s\"\n", frase, fraseout);
return 0;
}
fraseout is not long enough to hold the NULL terminating byte, so you need to make it one bigger:
char fraseout [size+1];
Also, after building fraseout, you need to make sure it's NULL terminated, otherwise you'll print garbage:
fraseout[size] = '\0';
There are two related points,
Need to take the size as strlen()+ 1, as strlen() does not take into account the terminating null.
Need to make the fraseout[i], the last element as 0 or '\0' to make it usable as a string.

word entry in an array of strings

I'm trying to make a program that will read up to 20 words entered by the user and stored in an array of strings. The program will ask for additional words until 20 words have been entered or until the word 'done' has been entered. The idea is that these words will then be entered into a matrix to create a word search program. I'm stuck on scanning in the words entered by the user. I'm a new programmer so any words of advice is very beneficial.
#include <stdio.h>
int main(void)
{
char string[20][100];
printf("Enter up to 20 words to hide in the puzzle.\n");
printf("Enter the word 'done' after your last word if entering less than 20 words.\n");
scanf("%s\n",c)
printf("Entered words:\n");
return 0;
}
#include<stdio.h>
#include<string.h>
int main(void)
{
char words[20][100];
char temp[100]="\0";
int i=0;
int end=0; //0 false and 1 true
printf("Enter 20 words or enter done to exit.\n");
while(i <=19 && end==0)
{
strset(temp,'\0');// resets array temp to NULL's everytime
scanf(" %99[^\n]",temp); //this is scan set, to read a string without '\n'
printf("Given:%s\n\n",temp);
if(strcmpi(temp,"done")==0)//compares given input with "done".if "done" is entered. zero is returned
end=1;//when 0 is returned this end=1 will break the loop.
else//if input is not given "done" then copy temp array to words[i].
{
strcpy(words[i],temp);
i++;
}
}
}
Instead of using words[20][100] directly, I have used a temporary array named temp to initially store the input,because at the end i don't want to store "done" into words[20][100].Assuming that "done" is used only to end the input process and it is not the actual word to store.But you can change this program to your need.
This is a straight-forward but bug-fixed variant of the code provided by developer3466402 in his answer.
I've used a for loop instead of a while loop since that neatly summarizes the action in the while loop. I added n to record how many words were entered, leaving i as a loop control variable (yes, once upon a long time ago I wrote Fortran too).
#include <stdio.h>
#include <string.h>
int main(void)
{
char words[20][100];
int i = 0;
int n;
printf("Enter up to 20 words to hide in the puzzle.\n");
printf("Enter the word 'done' after your last word if entering less than 20 words.\n");
for (i = 0; i < 20; i++)
{
printf("Enter word %2d:\n", i+1);
if (scanf("%99s", words[i]) != 1 || strcmp(words[i], "done") == 0)
break;
}
n = i;
printf("%d words entered\n", n);
for (i = 0; i < n; i++)
printf("Word %2d = [%s]\n", i+1, words[i]);
return 0;
}
It worked OK for me entering 0, 1, many and 20 words. We can debate the newline after the prompt; it has pros and cons, but that's generally true. I chose to echo the data after the loop rather than within the loop. Be aware that with some programs, echoing in a loop can appear to work where echoing after the loop shows a problem.
Example run (with an early exit):
$ ./rw
Enter up to 20 words to hide in the puzzle.
Enter the word 'done' after your last word if entering less than 20 words.
Enter word 1:
aleph
Enter word 2:
null
Enter word 3:
absolute
Enter word 4:
twaddle and nonsense
Enter word 5:
Enter word 6:
Enter word 7:
elephants are done for
Enter word 8:
Enter word 9:
8 words entered
Word 1 = [aleph]
Word 2 = [null]
Word 3 = [absolute]
Word 4 = [twaddle]
Word 5 = [and]
Word 6 = [nonsense]
Word 7 = [elephants]
Word 8 = [are]
$
You can dynamically allocate memory to store words. If the user inputs more than 20 words, then you can use realloc function to allocate more memory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int wlimit = 20;
int wcount = 0;
int retval; // to save the return value of scanf
char wstring[100+1]; // +1 for the terminating null byte
char **wlist = malloc(wlimit * sizeof *wlist);
if(wlist == NULL) {
// handle it
printf("not enough memory to allocate\n");
return 1;
}
char *temp;
while(1) {
if(wcount >= wlimit) {
wlimit *= 2;
temp = wlist;
wlist = realloc(wlist, wlimit);
if(temp == NULL) {
printf("not enough memory to allocate\n");
wlist = temp;
}
}
retval = scanf("%100s", wstring);
// if the input string is done, then break out of the
// loop else keep taking input from the user
if(retval != 1 || strcmp(wstring, "done") == 0)
break;
// strdup function creates a new string which is a duplicate
// of the input string and returns a pointer to it which can
// be freed using free
wlist[wcount++] = strdup(wstring);
}
// do stuff with wlist
// after done, free the memory
for(int i = 0; i < wcount; i++)
free(wlist[i]);
free(wlist);
wlist = NULL;
// stuff
return 0;
}
I think you wish something like below:
#include<stdio.h>
int main(void)
{
char words[20][100];
int i = 0;
printf("Enter up to 20 words to hide in the puzzle.\n");
printf("Enter the word 'done' after your last word if entering less than 20 words.\n");
while (i < 20) {
printf("Entered words:\n");
if (scanf("%99s", words[i]) != 1 || strcmp(words[i], "done") == 0)
break;
printf("%s\n", words[i]);
i++;
}
return 0;
}

Resources